diff options
author | 2012-01-25 19:43:13 +0900 | |
---|---|---|
committer | 2012-01-25 20:16:21 +0900 | |
commit | 09f8b126e532ca2ac6bbe00c0d78bf03e44b78a2 (patch) | |
tree | 366b0231210753fb7888e130430f91697da031fe /java/src | |
parent | bcf2b79365d7b655e973809c775772479dd8dff5 (diff) | |
download | latinime-09f8b126e532ca2ac6bbe00c0d78bf03e44b78a2.tar.gz latinime-09f8b126e532ca2ac6bbe00c0d78bf03e44b78a2.tar.xz latinime-09f8b126e532ca2ac6bbe00c0d78bf03e44b78a2.zip |
Add Key preserveCase enum to keyLabelOptions attribute
To support auto generate key depending keyboard element id, the
KeysCache class is introduced to hold whole keys and reuse.
Change-Id: Icb81b5f1c1b3aaa31968dcdb93aa0a856e737f78
Diffstat (limited to 'java/src')
3 files changed, 99 insertions, 31 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index caaed7ebb..9c495fd5f 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -71,6 +71,7 @@ public class Key { private static final int LABEL_FLAGS_WITH_ICON_LEFT = 0x1000; private static final int LABEL_FLAGS_WITH_ICON_RIGHT = 0x2000; private static final int LABEL_FLAGS_AUTO_X_SCALE = 0x4000; + private static final int LABEL_FLAGS_PRESERVE_CASE = 0x8000; /** Icon to display instead of a label. Icon takes precedence over a label */ private final int mIconAttrId; @@ -262,19 +263,6 @@ public class Key { // Update row to have current x coordinate. row.setXPos(keyXPos + keyWidth); - final String[] moreKeys = style.getStringArray(keyAttr, - R.styleable.Keyboard_Key_moreKeys); - // In Arabic symbol layouts, we'd like to keep digits in more keys regardless of - // config_digit_more_keys_enabled. - if (params.mId.isAlphabetKeyboard() - && !res.getBoolean(R.bool.config_digit_more_keys_enabled)) { - mMoreKeys = MoreKeySpecParser.filterOut(res, moreKeys, MoreKeySpecParser.DIGIT_FILTER); - } else { - mMoreKeys = moreKeys; - } - mMaxMoreKeysColumn = style.getInt(keyAttr, - R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMiniKeyboardColumn); - mBackgroundType = style.getInt(keyAttr, R.styleable.Keyboard_Key_backgroundType, BACKGROUND_TYPE_NORMAL); mActionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags, 0); @@ -292,14 +280,39 @@ public class Key { mDisabledIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled, KeyboardIconsSet.ICON_UNDEFINED)); - mLabel = style.getString(keyAttr, R.styleable.Keyboard_Key_keyLabel); - mHintLabel = style.getString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel); mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags, 0); - mOutputText = style.getString(keyAttr, R.styleable.Keyboard_Key_keyOutputText); + final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0; + + final String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys); + if (moreKeys != null) { + for (int i = 0; i < moreKeys.length; i++) { + moreKeys[i] = adjustCaseOfStringForKeyboardId( + moreKeys[i], preserveCase, params.mId); + } + } + // TODO: Add new key label flag to control this. + // In Arabic symbol layouts, we'd like to keep digits in more keys regardless of + // config_digit_more_keys_enabled. + if (params.mId.isAlphabetKeyboard() + && !res.getBoolean(R.bool.config_digit_more_keys_enabled)) { + mMoreKeys = MoreKeySpecParser.filterOut(res, moreKeys, MoreKeySpecParser.DIGIT_FILTER); + } else { + mMoreKeys = moreKeys; + } + mMaxMoreKeysColumn = style.getInt(keyAttr, + R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMiniKeyboardColumn); + + mLabel = adjustCaseOfStringForKeyboardId(style.getString( + keyAttr, R.styleable.Keyboard_Key_keyLabel), preserveCase, params.mId); + mHintLabel = adjustCaseOfStringForKeyboardId(style.getString( + keyAttr, R.styleable.Keyboard_Key_keyHintLabel), preserveCase, params.mId); + mOutputText = adjustCaseOfStringForKeyboardId(style.getString( + keyAttr, R.styleable.Keyboard_Key_keyOutputText), preserveCase, params.mId); // Choose the first letter of the label as primary code if not // specified. - final int code = style.getInt(keyAttr, R.styleable.Keyboard_Key_code, - Keyboard.CODE_UNSPECIFIED); + final int code = adjustCaseOfCodeForKeyboardId(style.getInt( + keyAttr, R.styleable.Keyboard_Key_code, Keyboard.CODE_UNSPECIFIED), preserveCase, + params.mId); if (code == Keyboard.CODE_UNSPECIFIED && mOutputText == null && !TextUtils.isEmpty(mLabel)) { if (mLabel.length() != 1) { @@ -312,13 +325,36 @@ public class Key { } else { mCode = code; } - mAltCode = style.getInt(keyAttr, - R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED); + mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr, + R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase, + params.mId); mHashCode = hashCode(this); keyAttr.recycle(); } + private static int adjustCaseOfCodeForKeyboardId(int code, boolean preserveCase, + KeyboardId id) { + if (!Keyboard.isLetterCode(code) || preserveCase) return code; + final String text = new String(new int[] { code } , 0, 1); + final String casedText = adjustCaseOfStringForKeyboardId(text, preserveCase, id); + return casedText.codePointAt(0); + } + + private static String adjustCaseOfStringForKeyboardId(String text, boolean preserveCase, + KeyboardId id) { + if (text == null || preserveCase) return text; + switch (id.mElementId) { + case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED: + case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: + case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED: + case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: + return text.toUpperCase(id.mLocale); + default: + return text; + } + } + private static int hashCode(Key key) { return Arrays.hashCode(new Object[] { key.mX, diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 72fc33809..abe5b62ee 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -293,6 +293,8 @@ public class Keyboard { public final Set<Key> mShiftLockKeys = new HashSet<Key>(); public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet(); + public KeyboardSet.KeysCache mKeysCache; + public int mMostCommonKeyHeight = 0; public int mMostCommonKeyWidth = 0; @@ -361,7 +363,8 @@ public class Keyboard { clearHistogram(); } - public void onAddKey(Key key) { + public void onAddKey(Key newKey) { + final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey; mKeys.add(key); updateHistogram(key); if (key.mCode == Keyboard.CODE_SHIFT) { @@ -688,6 +691,10 @@ public class Keyboard { params.mTouchPositionCorrection.load(data); } + public void setAutoGenerate(KeyboardSet.KeysCache keysCache) { + mParams.mKeysCache = keysCache; + } + public Builder<KP> load(int xmlId, KeyboardId id) { mParams.mId = id; final XmlResourceParser parser = mResources.getXml(xmlId); diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java index c7f964aaa..cacb8a324 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSet.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSet.java @@ -57,6 +57,25 @@ public class KeyboardSet { private final Context mContext; private final Params mParams; + private final KeysCache mKeysCache = new KeysCache(); + + public static class KeysCache { + private final Map<Key, Key> mMap; + + public KeysCache() { + mMap = new HashMap<Key, Key>(); + } + + 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; + } + } static class KeyboardElement { final int mElementId; @@ -99,15 +118,15 @@ public class KeyboardSet { } public Keyboard getMainKeyboard() { - return getKeyboard(false, false); + return getKeyboard(false, false, false); } public Keyboard getSymbolsKeyboard() { - return getKeyboard(true, false); + return getKeyboard(true, false, false); } public Keyboard getSymbolsShiftedKeyboard() { - final Keyboard keyboard = getKeyboard(true, true); + final Keyboard keyboard = getKeyboard(true, false, true); // TODO: Remove this logic once we introduce initial keyboard shift state attribute. // Symbol shift keyboard may have a shift key that has a caps lock style indicator (a.k.a. // sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked() @@ -116,22 +135,23 @@ public class KeyboardSet { return keyboard; } - private Keyboard getKeyboard(boolean isSymbols, boolean isShift) { - final int elementId = KeyboardSet.getElementId(mParams.mMode, isSymbols, isShift); + private Keyboard getKeyboard(boolean isSymbols, boolean isShiftLock, boolean isShift) { + final int elementId = KeyboardSet.getElementId( + mParams.mMode, isSymbols, isShiftLock, isShift); final KeyboardElement keyboardElement = mParams.mElementKeyboards.get(elementId); // TODO: If keyboardElement.mAutoGenerate is true, the keyboard will be auto generated // based on keyboardElement.mKayoutId Keyboard XML definition. final KeyboardId id = KeyboardSet.getKeyboardId(elementId, isSymbols, mParams); - final Keyboard keyboard = getKeyboard(mContext, keyboardElement.mLayoutId, id); + final Keyboard keyboard = getKeyboard(mContext, keyboardElement, id); return keyboard; } public KeyboardId getMainKeyboardId() { - final int elementId = KeyboardSet.getElementId(mParams.mMode, false, false); + final int elementId = KeyboardSet.getElementId(mParams.mMode, false, false, false); return KeyboardSet.getKeyboardId(elementId, false, mParams); } - private Keyboard getKeyboard(Context context, int xmlId, KeyboardId id) { + private Keyboard getKeyboard(Context context, KeyboardElement element, KeyboardId id) { final Resources res = context.getResources(); final SoftReference<Keyboard> ref = sKeyboardCache.get(id); Keyboard keyboard = (ref == null) ? null : ref.get(); @@ -140,7 +160,10 @@ public class KeyboardSet { try { final Keyboard.Builder<Keyboard.Params> builder = new Keyboard.Builder<Keyboard.Params>(context, new Keyboard.Params()); - builder.load(xmlId, id); + if (element.mAutoGenerate) { + builder.setAutoGenerate(mKeysCache); + } + builder.load(element.mLayoutId, id); builder.setTouchPositionCorrectionEnabled(mParams.mTouchPositionCorrectionEnabled); keyboard = builder.build(); } finally { @@ -162,7 +185,8 @@ public class KeyboardSet { return keyboard; } - private static int getElementId(int mode, boolean isSymbols, boolean isShift) { + private static int getElementId(int mode, boolean isSymbols, boolean isShiftLock, + boolean isShift) { switch (mode) { case KeyboardId.MODE_PHONE: return (isSymbols && isShift) @@ -174,6 +198,7 @@ public class KeyboardSet { return isShift ? KeyboardId.ELEMENT_SYMBOLS_SHIFTED : KeyboardId.ELEMENT_SYMBOLS; } + // TODO: Consult isShiftLock and isShift to determine the element. return KeyboardId.ELEMENT_ALPHABET; } } |