Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1b709fe9 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android Git Automerger
Browse files

am 09f8b126: Add Key preserveCase enum to keyLabelOptions attribute

* commit '09f8b126':
  Add Key preserveCase enum to keyLabelOptions attribute
parents bf57d2c8 09f8b126
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -242,6 +242,9 @@
            <flag name="withIconLeft" value="0x1000" />
            <flag name="withIconRight" value="0x2000" />
            <flag name="autoXScale" value="0x4000" />
            <!-- If true, character case of code, altCode, moreKeys, keyOutputText, keyLabel,
                 or keyHintLabel will never be subject to change. -->
            <flag name="preserveCase" value="0x8000" />
        </attr>
        <!-- The icon to display on the key instead of the label. -->
        <attr name="keyIcon" format="enum">
+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@
    latin:keyboardLocale="en_GB,en_US">
    <Element
        latin:elementName="alphabet"
        latin:elementKeyboard="@xml/kbd_qwerty" />
        latin:elementKeyboard="@xml/kbd_qwerty"
        latin:elementAutoGenerate="true" />
    <Element
        latin:elementName="alphabetManualShifted"
        latin:elementKeyboard="@xml/kbd_qwerty"
+56 −20
Original line number Diff line number Diff line
@@ -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,
+8 −1
Original line number Diff line number Diff line
@@ -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);
+35 −10
Original line number Diff line number Diff line
@@ -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;
        }
    }