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/KeyDetector.java63
-rw-r--r--java/src/com/android/inputmethod/keyboard/Keyboard.java20
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java46
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSet.java9
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java24
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java5
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java86
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java3
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java71
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java11
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java24
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java7
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java7
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsValues.java19
15 files changed, 257 insertions, 171 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/KeyDetector.java b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
index bff491ffd..0ce98d2f1 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyDetector.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyDetector.java
@@ -180,32 +180,34 @@ public class KeyDetector {
if (maxCodesSize <= numCodes) {
return;
}
- if (primaryCode != NOT_A_CODE) {
- final List<Integer> additionalChars =
- mKeyboard.getAdditionalProximityChars().get(primaryCode);
- if (additionalChars == null || additionalChars.size() == 0) {
- return;
- }
- int currentCodesSize = numCodes;
- allCodes[numCodes++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
- if (maxCodesSize <= numCodes) {
- return;
- }
- // TODO: This is O(N^2). Assuming additionalChars.size() is up to 4 or 5.
- for (int i = 0; i < additionalChars.size(); ++i) {
- final int additionalChar = additionalChars.get(i);
- boolean contains = false;
- for (int j = 0; j < currentCodesSize; ++j) {
- if (additionalChar == allCodes[j]) {
- contains = true;
- break;
- }
+
+ final int code = (primaryCode == NOT_A_CODE) ? allCodes[0] : primaryCode;
+ if (code == NOT_A_CODE) {
+ return;
+ }
+ final List<Integer> additionalChars = mKeyboard.getAdditionalProximityChars().get(code);
+ if (additionalChars == null || additionalChars.size() == 0) {
+ return;
+ }
+ int currentCodesSize = numCodes;
+ allCodes[numCodes++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
+ if (maxCodesSize <= numCodes) {
+ return;
+ }
+ // TODO: This is O(N^2). Assuming additionalChars.size() is up to 4 or 5.
+ for (int i = 0; i < additionalChars.size(); ++i) {
+ final int additionalChar = additionalChars.get(i);
+ boolean contains = false;
+ for (int j = 0; j < currentCodesSize; ++j) {
+ if (additionalChar == allCodes[j]) {
+ contains = true;
+ break;
}
- if (!contains) {
- allCodes[numCodes++] = additionalChar;
- if (maxCodesSize <= numCodes) {
- return;
- }
+ }
+ if (!contains) {
+ allCodes[numCodes++] = additionalChar;
+ if (maxCodesSize <= numCodes) {
+ return;
}
}
}
@@ -257,10 +259,17 @@ public class KeyDetector {
public static String printableCodes(int[] codes) {
final StringBuilder sb = new StringBuilder();
+ boolean addDelimiter = false;
for (final int code : codes) {
if (code == NOT_A_CODE) break;
- if (sb.length() > 0) sb.append(", ");
- sb.append(code);
+ if (code == ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) {
+ sb.append(" | ");
+ addDelimiter = false;
+ } else {
+ if (addDelimiter) sb.append(", ");
+ sb.append(code);
+ addDelimiter = true;
+ }
}
return "[" + sb + "]";
}
diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java
index 28f71f443..60e506914 100644
--- a/java/src/com/android/inputmethod/keyboard/Keyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java
@@ -1073,10 +1073,6 @@ public class Keyboard {
R.styleable.Keyboard_Case_navigateAction, id.navigateAction());
final boolean passwordInputMatched = matchBoolean(a,
R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
- final boolean hasSettingsKeyMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_hasSettingsKey, id.hasSettingsKey());
- final boolean f2KeyModeMatched = matchInteger(a,
- R.styleable.Keyboard_Case_f2KeyMode, id.f2KeyMode());
final boolean clobberSettingsKeyMatched = matchBoolean(a,
R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
final boolean shortcutKeyEnabledMatched = matchBoolean(a,
@@ -1094,14 +1090,13 @@ public class Keyboard {
final boolean countryCodeMatched = matchString(a,
R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
final boolean selected = keyboardSetElementMatched && modeMatched
- && navigateActionMatched && passwordInputMatched && hasSettingsKeyMatched
- && f2KeyModeMatched && clobberSettingsKeyMatched
- && shortcutKeyEnabledMatched && hasShortcutKeyMatched && isMultiLineMatched
- && imeActionMatched && localeCodeMatched && languageCodeMatched
- && countryCodeMatched;
+ && navigateActionMatched && passwordInputMatched
+ && clobberSettingsKeyMatched && shortcutKeyEnabledMatched
+ && hasShortcutKeyMatched && 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,
+ startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
textAttr(a.getString(R.styleable.Keyboard_Case_keyboardSetElement),
"keyboardSetElement"),
textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
@@ -1109,11 +1104,6 @@ public class Keyboard {
"navigateAction"),
booleanAttr(a, R.styleable.Keyboard_Case_passwordInput,
"passwordInput"),
- booleanAttr(a, R.styleable.Keyboard_Case_hasSettingsKey,
- "hasSettingsKey"),
- textAttr(KeyboardId.f2KeyModeName(
- a.getInt(R.styleable.Keyboard_Case_f2KeyMode, -1)),
- "f2KeyMode"),
booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
"clobberSettingsKey"),
booleanAttr(a, R.styleable.Keyboard_Case_shortcutKeyEnabled,
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index 3ab24933c..a75caf262 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -48,11 +48,6 @@ public class KeyboardId {
public static final int ELEMENT_PHONE_SYMBOLS = 8;
public static final int ELEMENT_NUMBER = 9;
- private static final int F2KEY_MODE_NONE = 0;
- private static final int F2KEY_MODE_SETTINGS = 1;
- private static final int F2KEY_MODE_SHORTCUT_IME = 2;
- private static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
-
private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1;
public final Locale mLocale;
@@ -61,7 +56,6 @@ public class KeyboardId {
public final int mMode;
public final int mElementId;
private final EditorInfo mEditorInfo;
- private final boolean mSettingsKeyEnabled;
public final boolean mClobberSettingsKey;
public final boolean mShortcutKeyEnabled;
public final boolean mHasShortcutKey;
@@ -70,15 +64,14 @@ public class KeyboardId {
private final int mHashCode;
public KeyboardId(int elementId, Locale locale, int orientation, int width, int mode,
- EditorInfo editorInfo, boolean settingsKeyEnabled, boolean clobberSettingsKey,
- boolean shortcutKeyEnabled, boolean hasShortcutKey) {
+ EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled,
+ boolean hasShortcutKey) {
this.mLocale = locale;
this.mOrientation = orientation;
this.mWidth = width;
this.mMode = mode;
this.mElementId = elementId;
this.mEditorInfo = editorInfo;
- this.mSettingsKeyEnabled = settingsKeyEnabled;
this.mClobberSettingsKey = clobberSettingsKey;
this.mShortcutKeyEnabled = shortcutKeyEnabled;
this.mHasShortcutKey = hasShortcutKey;
@@ -96,7 +89,6 @@ public class KeyboardId {
id.mWidth,
id.navigateAction(),
id.passwordInput(),
- id.mSettingsKeyEnabled,
id.mClobberSettingsKey,
id.mShortcutKeyEnabled,
id.mHasShortcutKey,
@@ -116,7 +108,6 @@ public class KeyboardId {
&& other.mWidth == this.mWidth
&& other.navigateAction() == this.navigateAction()
&& other.passwordInput() == this.passwordInput()
- && other.mSettingsKeyEnabled == this.mSettingsKeyEnabled
&& other.mClobberSettingsKey == this.mClobberSettingsKey
&& other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
&& other.mHasShortcutKey == this.mHasShortcutKey
@@ -183,25 +174,6 @@ public class KeyboardId {
}
}
- public boolean hasSettingsKey() {
- return mSettingsKeyEnabled && !mClobberSettingsKey;
- }
-
- public int f2KeyMode() {
- if (mClobberSettingsKey) {
- // Never shows the Settings key
- return KeyboardId.F2KEY_MODE_SHORTCUT_IME;
- }
-
- if (mSettingsKeyEnabled) {
- return KeyboardId.F2KEY_MODE_SETTINGS;
- } else {
- // It should be alright to fall back to the Settings key on 7-inch layouts
- // even when the Settings key is not explicitly enabled.
- return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS;
- }
- }
-
@Override
public boolean equals(Object other) {
return other instanceof KeyboardId && equals((KeyboardId) other);
@@ -214,17 +186,15 @@ public class KeyboardId {
@Override
public String toString() {
- return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]",
+ return String.format("[%s %s %s%d %s %s %s%s%s%s%s]",
elementIdToName(mElementId),
mLocale,
(mOrientation == 1 ? "port" : "land"), mWidth,
modeName(mMode),
imeAction(),
- f2KeyModeName(f2KeyMode()),
(mClobberSettingsKey ? " clobberSettingsKey" : ""),
(navigateAction() ? " navigateAction" : ""),
(passwordInput() ? " passwordInput" : ""),
- (hasSettingsKey() ? " hasSettingsKey" : ""),
(mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
(mHasShortcutKey ? " hasShortcutKey" : "")
);
@@ -270,14 +240,4 @@ public class KeyboardId {
return (actionId == IME_ACTION_CUSTOM_LABEL) ? "actionCustomLabel"
: EditorInfoCompatUtils.imeActionName(actionId);
}
-
- public static String f2KeyModeName(int f2KeyMode) {
- switch (f2KeyMode) {
- case F2KEY_MODE_NONE: return "none";
- case F2KEY_MODE_SETTINGS: return "settings";
- case F2KEY_MODE_SHORTCUT_IME: return "shortcutIme";
- case F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS: return "shortcutImeOrSettings";
- default: return null;
- }
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
index f27170a89..6e62f743b 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java
@@ -98,7 +98,6 @@ public class KeyboardSet {
int mMode;
EditorInfo mEditorInfo;
boolean mTouchPositionCorrectionEnabled;
- boolean mSettingsKeyEnabled;
boolean mVoiceKeyEnabled;
boolean mVoiceKeyOnMain;
boolean mNoSettingsKey;
@@ -193,8 +192,8 @@ public class KeyboardSet {
final boolean hasShortcutKey = params.mVoiceKeyEnabled
&& (isSymbols != params.mVoiceKeyOnMain);
return new KeyboardId(keyboardSetElementId, params.mLocale, params.mOrientation,
- params.mWidth, params.mMode, params.mEditorInfo, params.mSettingsKeyEnabled,
- params.mNoSettingsKey, params.mVoiceKeyEnabled, hasShortcutKey);
+ params.mWidth, params.mMode, params.mEditorInfo, params.mNoSettingsKey,
+ params.mVoiceKeyEnabled, hasShortcutKey);
}
public static class Builder {
@@ -237,9 +236,7 @@ public class KeyboardSet {
return this;
}
- public Builder setOptions(boolean settingsKeyEnabled, boolean voiceKeyEnabled,
- boolean voiceKeyOnMain) {
- mParams.mSettingsKeyEnabled = settingsKeyEnabled;
+ public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain) {
@SuppressWarnings("deprecation")
final boolean deprecatedNoMicrophone = Utils.inPrivateImeOptions(
null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, mEditorInfo);
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 5ba560d72..622e5831f 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -35,7 +35,6 @@ import com.android.inputmethod.latin.InputView;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.Settings;
import com.android.inputmethod.latin.SettingsValues;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Utils;
@@ -133,7 +132,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
builder.setOptions(
- settingsValues.isSettingsKeyEnabled(),
settingsValues.isVoiceKeyEnabled(editorInfo),
settingsValues.isVoiceKeyOnMain());
mKeyboardSet = builder.build();
@@ -268,6 +266,16 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
// Implements {@link KeyboardState.SwitchActions}.
@Override
+ public void cancelDoubleTapTimer() {
+ final LatinKeyboardView keyboardView = getKeyboardView();
+ if (keyboardView != null) {
+ final TimerProxy timer = keyboardView.getTimerProxy();
+ timer.cancelDoubleTapTimer();
+ }
+ }
+
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
public boolean isInDoubleTapTimeout() {
final LatinKeyboardView keyboardView = getKeyboardView();
return (keyboardView != null)
@@ -286,6 +294,16 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
// Implements {@link KeyboardState.SwitchActions}.
@Override
+ public void cancelLongPressTimer() {
+ final LatinKeyboardView keyboardView = getKeyboardView();
+ if (keyboardView != null) {
+ final TimerProxy timer = keyboardView.getTimerProxy();
+ timer.cancelLongPressTimer();
+ }
+ }
+
+ // Implements {@link KeyboardState.SwitchActions}.
+ @Override
public void hapticAndAudioFeedback(int code) {
mInputMethodService.hapticAndAudioFeedback(code);
}
@@ -384,8 +402,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
if (PREF_KEYBOARD_LAYOUT.equals(key)) {
final int themeIndex = getKeyboardThemeIndex(mInputMethodService, sharedPreferences);
postSetInputView(createInputView(themeIndex, false));
- } else if (Settings.PREF_SHOW_SETTINGS_KEY.equals(key)) {
- postSetInputView(createInputView(mThemeIndex, true));
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 88a41579d..9a0fe1efa 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -233,6 +233,11 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
}
@Override
+ public void cancelDoubleTapTimer() {
+ removeMessages(MSG_DOUBLE_TAP);
+ }
+
+ @Override
public boolean isInDoubleTapTimeout() {
return hasMessages(MSG_DOUBLE_TAP);
}
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/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 110f7f6ae..c45308419 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -77,6 +77,7 @@ public class PointerTracker {
public void startLongPressTimer(int code);
public void cancelLongPressTimer();
public void startDoubleTapTimer();
+ public void cancelDoubleTapTimer();
public boolean isInDoubleTapTimeout();
public void cancelKeyTimers();
@@ -96,6 +97,8 @@ public class PointerTracker {
@Override
public void startDoubleTapTimer() {}
@Override
+ public void cancelDoubleTapTimer() {}
+ @Override
public boolean isInDoubleTapTimeout() { return false; }
@Override
public void cancelKeyTimers() {}
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;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
index cb8b4f05c..6a8a03677 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardState.java
@@ -54,7 +54,9 @@ public class KeyboardState {
public void startDoubleTapTimer();
public boolean isInDoubleTapTimeout();
+ public void cancelDoubleTapTimer();
public void startLongPressTimer(int code);
+ public void cancelLongPressTimer();
public void hapticAndAudioFeedback(int code);
}
@@ -300,6 +302,8 @@ public class KeyboardState {
} else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
onPressSymbol();
} else {
+ mSwitchActions.cancelDoubleTapTimer();
+ mSwitchActions.cancelLongPressTimer();
mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
}
@@ -348,7 +352,7 @@ public class KeyboardState {
// state. And mark as if shift key is released.
mShiftKeyState.onRelease();
} else {
- // Shift key is long pressed while shift unloked state.
+ // Shift key is long pressed while shift unlocked state.
setShiftLocked(true);
}
mSwitchActions.hapticAndAudioFeedback(code);
@@ -364,6 +368,11 @@ public class KeyboardState {
private void updateAlphabetShiftState(boolean autoCaps) {
if (!mIsAlphabetMode) return;
+ if (!mShiftKeyState.isReleasing()) {
+ // Ignore update shift state event while the shift key is being pressed (including
+ // chording).
+ return;
+ }
if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) {
if (mShiftKeyState.isReleasing() && autoCaps) {
// Only when shift key is releasing, automatic temporary upper case will be set.
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index d9181f786..5db65c660 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -16,12 +16,18 @@
package com.android.inputmethod.keyboard.internal;
+import android.util.Log;
+
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.PointerTracker;
import java.util.Iterator;
import java.util.LinkedList;
public class PointerTrackerQueue {
+ private static final String TAG = PointerTrackerQueue.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
private final LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>();
public synchronized void add(PointerTracker tracker) {
@@ -32,7 +38,11 @@ public class PointerTrackerQueue {
mQueue.remove(tracker);
}
- public synchronized void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) {
+ public synchronized void releaseAllPointersOlderThan(PointerTracker tracker,
+ long eventTime) {
+ if (DEBUG) {
+ Log.d(TAG, "releaseAllPoniterOlderThan: [" + tracker.mPointerId + "] " + this);
+ }
if (!mQueue.contains(tracker)) {
return;
}
@@ -54,6 +64,13 @@ public class PointerTrackerQueue {
}
public synchronized void releaseAllPointersExcept(PointerTracker tracker, long eventTime) {
+ if (DEBUG) {
+ if (tracker == null) {
+ Log.d(TAG, "releaseAllPoniters: " + this);
+ } else {
+ Log.d(TAG, "releaseAllPoniterExcept: [" + tracker.mPointerId + "] " + this);
+ }
+ }
final Iterator<PointerTracker> it = mQueue.iterator();
while (it.hasNext()) {
final PointerTracker t = it.next();
@@ -79,8 +96,9 @@ public class PointerTrackerQueue {
for (final PointerTracker tracker : mQueue) {
if (sb.length() > 0)
sb.append(" ");
- sb.append(tracker.mPointerId);
+ sb.append("[" + tracker.mPointerId + " "
+ + Keyboard.printableCode(tracker.getKey().mCode) + "]");
}
- return "[" + sb + "]";
+ return sb.toString();
}
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 1cb79e707..730992b13 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -325,7 +325,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return hasMessages(MSG_UPDATE_SUGGESTIONS);
}
- public void postUpdateShiftKeyState() {
+ public void postUpdateShiftState() {
removeMessages(MSG_UPDATE_SHIFT_STATE);
sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState);
}
@@ -898,9 +898,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions();
}
+
+ mHandler.postUpdateShiftState();
}
mExpectingUpdateSelection = false;
- mHandler.postUpdateShiftKeyState();
// TODO: Decide to call restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() or not
// here. It would probably be too expensive to call directly here but we may want to post a
// message to delay it. The point would be to unify behavior between backspace to the
@@ -1391,7 +1392,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mVoiceProxy.handleBackspace();
// In many cases, we may have to put the keyboard in auto-shift state again.
- mHandler.postUpdateShiftKeyState();
+ mHandler.postUpdateShiftState();
if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
// Cancel multi-character input: remove the text we just entered.
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index d32310096..dfcb6450e 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -65,7 +65,6 @@ public class Settings extends InputMethodSettingsActivity
public static final String PREF_VIBRATE_ON = "vibrate_on";
public static final String PREF_SOUND_ON = "sound_on";
public static final String PREF_POPUP_ON = "popup_on";
- public static final String PREF_SHOW_SETTINGS_KEY = "show_settings_key";
public static final String PREF_VOICE_MODE = "voice_mode";
public static final String PREF_CORRECTION_SETTINGS = "correction_settings";
public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
@@ -96,7 +95,6 @@ public class Settings extends InputMethodSettingsActivity
private PreferenceScreen mKeypressVibrationDurationSettingsPref;
private PreferenceScreen mKeypressSoundVolumeSettingsPref;
private ListPreference mVoicePreference;
- private CheckBoxPreference mShowSettingsKeyPreference;
private ListPreference mShowCorrectionSuggestionsPreference;
private ListPreference mAutoCorrectionThresholdPreference;
private ListPreference mKeyPreviewPopupDismissDelay;
@@ -147,7 +145,6 @@ public class Settings extends InputMethodSettingsActivity
mInputLanguageSelection = (PreferenceScreen) findPreference(PREF_SUBTYPES_SETTINGS);
mInputLanguageSelection.setOnPreferenceClickListener(this);
mVoicePreference = (ListPreference) findPreference(PREF_VOICE_MODE);
- mShowSettingsKeyPreference = (CheckBoxPreference) findPreference(PREF_SHOW_SETTINGS_KEY);
mShowCorrectionSuggestionsPreference =
(ListPreference) findPreference(PREF_SHOW_SUGGESTIONS_SETTING);
SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
@@ -178,10 +175,6 @@ public class Settings extends InputMethodSettingsActivity
final PreferenceGroup miscSettings =
(PreferenceGroup) findPreference(PREF_MISC_SETTINGS);
- if (!SettingsValues.isShowSettingsKeyOptionEnabled(res)) {
- generalSettings.removePreference(mShowSettingsKeyPreference);
- }
-
final boolean showVoiceKeyOption = res.getBoolean(
R.bool.config_enable_show_voice_key_option);
if (!showVoiceKeyOption) {
diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java
index 6b652313c..7a43cb827 100644
--- a/java/src/com/android/inputmethod/latin/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/SettingsValues.java
@@ -49,7 +49,6 @@ public class SettingsValues {
public final boolean mVibrateOn;
public final boolean mSoundOn;
public final boolean mKeyPreviewPopupOn;
- private final boolean mShowSettingsKey;
private final String mVoiceMode;
private final String mAutoCorrectionThresholdRawValue;
public final String mShowSuggestionsSetting;
@@ -118,7 +117,6 @@ public class SettingsValues {
mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
res.getBoolean(R.bool.config_default_sound_enabled));
mKeyPreviewPopupOn = isKeyPreviewPopupEnabled(prefs, res);
- mShowSettingsKey = isSettingsKeyShown(prefs, res);
final String voiceModeMain = res.getString(R.string.voice_mode_main);
final String voiceModeOff = res.getString(R.string.voice_mode_off);
mVoiceMode = prefs.getString(Settings.PREF_VOICE_MODE, voiceModeMain);
@@ -202,19 +200,6 @@ public class SettingsValues {
return wordSeparators;
}
- private static boolean isSettingsKeyShown(final SharedPreferences prefs, final Resources res) {
- final boolean defaultShowSettingsKey = res.getBoolean(
- R.bool.config_default_show_settings_key);
- return isShowSettingsKeyOptionEnabled(res)
- ? prefs.getBoolean(Settings.PREF_SHOW_SETTINGS_KEY, defaultShowSettingsKey)
- : defaultShowSettingsKey;
- }
-
- public static boolean isShowSettingsKeyOptionEnabled(final Resources resources) {
- // TODO: Read this once and for all into a public final member
- return resources.getBoolean(R.bool.config_enable_show_settings_key_option);
- }
-
private static boolean isVibrateOn(final Context context, final SharedPreferences prefs,
final Resources res) {
final boolean hasVibrator = VibratorCompatWrapper.getInstance(context).hasVibrator();
@@ -306,10 +291,6 @@ public class SettingsValues {
return autoCorrectionThreshold;
}
- public boolean isSettingsKeyEnabled() {
- return mShowSettingsKey;
- }
-
public boolean isVoiceKeyEnabled(final EditorInfo editorInfo) {
final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled();
final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;