diff options
| author | Tadashi G. Takaoka <takaoka@google.com> | 2012-01-26 18:03:30 +0900 |
|---|---|---|
| committer | Tadashi G. Takaoka <takaoka@google.com> | 2012-01-31 12:55:45 +0900 |
| commit | ca2f051cc173acc3bce384ebfe08068564bc8e07 (patch) | |
| tree | e6521ddbe372710fd703dac4574552e8b7e96e3c /java/src/com/android/inputmethod/keyboard/Key.java | |
| parent | 3b0f2bf169c23ea94c5a0adb275ce41b5c34ea83 (diff) | |
Auto generate various shift states alphabet keyboard automatically
If any shift state variants of alphabet keyboard layout is not
specified in KeyboardSet.Element, it will be automatically generated
from base alphabet keyboard definition.
This change also
* Eliminates KeyboardShiftState object from Keyboard.
* Removes various set shift state methods from Keyboard.
* Removes KeyboardSet.Element.elementAutoGenerate attribute.
* Separates "sticky" Key.backgroundType to "stickyOff" and "stickyOn"
* Add preserveCase flag to smiley, .com, and labeled special keys.
* Rename KeyboardShiftState class to AlphabetShiftState.
* Rename some attributes from *UppercaseLetter* to *ShiftedLetterHint*.
* Introduce shiftedLetterActivated to Key.keyLabelFlags
Change-Id: I01a0a8efeeaa76820ae728a5bdfa8d02b6ce74b7
Diffstat (limited to 'java/src/com/android/inputmethod/keyboard/Key.java')
| -rw-r--r-- | java/src/com/android/inputmethod/keyboard/Key.java | 107 |
1 files changed, 58 insertions, 49 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index a2d379643..d4419aeaf 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -66,14 +66,13 @@ public class Key { private static final int LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO = 0x80; private static final int LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO = 0x100; private static final int LABEL_FLAGS_HAS_POPUP_HINT = 0x200; - private static final int LABEL_FLAGS_HAS_UPPERCASE_LETTER = 0x400; + private static final int LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT = 0x400; private static final int LABEL_FLAGS_HAS_HINT_LABEL = 0x800; 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; - private static final int LABEL_FLAGS_INACTIVATED_LABEL = 0x10000; - private static final int LABEL_FLAGS_INACTIVATED_UPPERCASE_LETTER = 0x20000; + private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x10000; /** Icon to display instead of a label. Icon takes precedence over a label */ private final int mIconAttrId; @@ -114,7 +113,8 @@ public class Key { public static final int BACKGROUND_TYPE_NORMAL = 0; public static final int BACKGROUND_TYPE_FUNCTIONAL = 1; public static final int BACKGROUND_TYPE_ACTION = 2; - public static final int BACKGROUND_TYPE_STICKY = 3; + public static final int BACKGROUND_TYPE_STICKY_OFF = 3; + public static final int BACKGROUND_TYPE_STICKY_ON = 4; private final int mActionFlags; private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01; @@ -125,8 +125,6 @@ public class Key { /** The current pressed state of this key */ private boolean mPressed; - /** If this is a sticky key, is its highlight on? */ - private boolean mHighlightOn; /** Key is enabled and responds on press */ private boolean mEnabled = true; @@ -303,31 +301,46 @@ public class Key { 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( + String outputText = 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 = adjustCaseOfCodeForKeyboardId(style.getInt( - keyAttr, R.styleable.Keyboard_Key_code, Keyboard.CODE_UNSPECIFIED), preserveCase, - params.mId); - if (code == Keyboard.CODE_UNSPECIFIED && mOutputText == null + final int code = style.getInt( + keyAttr, R.styleable.Keyboard_Key_code, Keyboard.CODE_UNSPECIFIED); + // Choose the first letter of the label as primary code if not specified. + if (code == Keyboard.CODE_UNSPECIFIED && TextUtils.isEmpty(outputText) && !TextUtils.isEmpty(mLabel)) { - if (mLabel.length() != 1) { - Log.w(TAG, "Label is not a single letter: label=" + mLabel); + if (mLabel.codePointCount(0, mLabel.length()) == 1) { + final int activatedCode; + // Use the first letter of the hint label if shiftedLetterActivated flag is + // specified. + if (hasShiftedLetterHint() && isShiftedLetterActivated() + && !TextUtils.isEmpty(mHintLabel)) { + activatedCode = mHintLabel.codePointAt(0); + } else { + activatedCode = mLabel.codePointAt(0); + } + mCode = getRtlParenthesisCode(activatedCode, params.mIsRtlKeyboard); + } else { + // In some locale and case, the character might be represented by multiple code + // points, such as upper case Eszett of German alphabet. + outputText = mLabel; + mCode = Keyboard.CODE_OUTPUT_TEXT; } - final int firstChar = mLabel.charAt(0); - mCode = getRtlParenthesisCode(firstChar, params.mIsRtlKeyboard); - } else if (code == Keyboard.CODE_UNSPECIFIED && mOutputText != null) { + } else if (code == Keyboard.CODE_UNSPECIFIED && outputText != null) { mCode = Keyboard.CODE_OUTPUT_TEXT; } else { - mCode = code; + mCode = adjustCaseOfCodeForKeyboardId(code, preserveCase, params.mId); } + mOutputText = outputText; mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr, R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase, params.mId); mHashCode = hashCode(this); keyAttr.recycle(); + + if (hasShiftedLetterHint() && TextUtils.isEmpty(mHintLabel)) { + Log.w(TAG, "hasShiftedLetterHint specified without keyHintLabel: " + this); + } } private static int adjustCaseOfCodeForKeyboardId(int code, boolean preserveCase, @@ -335,7 +348,8 @@ public class Key { 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); + return casedText.codePointCount(0, casedText.length()) == 1 + ? casedText.codePointAt(0) : Keyboard.CODE_UNSPECIFIED; } private static String adjustCaseOfStringForKeyboardId(String text, boolean preserveCase, @@ -362,6 +376,7 @@ public class Key { key.mLabel, key.mHintLabel, key.mIconAttrId, + key.mBackgroundType, // Key can be distinguishable without the following members. // key.mAltCode, // key.mOutputText, @@ -370,7 +385,6 @@ public class Key { // key.mIcon, // key.mDisabledIconAttrId, // key.mPreviewIconAttrId, - // key.mBackgroundType, // key.mHorizontalGap, // key.mVerticalGap, // key.mVisualInsetLeft, @@ -388,7 +402,9 @@ public class Key { && o.mHeight == mHeight && o.mCode == mCode && TextUtils.equals(o.mLabel, mLabel) - && TextUtils.equals(o.mHintLabel, mHintLabel); + && TextUtils.equals(o.mHintLabel, mHintLabel) + && o.mIconAttrId != mIconAttrId + && o.mBackgroundType != mBackgroundType; } @Override @@ -401,6 +417,15 @@ public class Key { return o instanceof Key && equals((Key)o); } + @Override + public String toString() { + String top = Keyboard.printableCode(mCode); + if (mLabel != null && mLabel.length() != 1) { + top += "/\"" + mLabel + '"'; + } + return String.format("%s %d,%d", top, mX, mY); + } + public void markAsLeftEdge(Keyboard.Params params) { mHitBox.left = params.mHorizontalEdgesPadding; } @@ -417,10 +442,6 @@ public class Key { mHitBox.bottom = params.mOccupiedHeight + params.mBottomPadding; } - public boolean isSticky() { - return mBackgroundType == BACKGROUND_TYPE_STICKY; - } - public boolean isSpacer() { return false; } @@ -486,8 +507,8 @@ public class Key { return (mLabelFlags & LABEL_FLAGS_HAS_POPUP_HINT) != 0; } - public boolean hasUppercaseLetter() { - return (mLabelFlags & LABEL_FLAGS_HAS_UPPERCASE_LETTER) != 0; + public boolean hasShiftedLetterHint() { + return (mLabelFlags & LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT) != 0; } public boolean hasHintLabel() { @@ -506,12 +527,8 @@ public class Key { return (mLabelFlags & LABEL_FLAGS_AUTO_X_SCALE) != 0; } - public boolean isInactivatedLabel() { - return (mLabelFlags & LABEL_FLAGS_INACTIVATED_LABEL) != 0; - } - - public boolean isInactivatedUppercaseLetter() { - return (mLabelFlags & LABEL_FLAGS_INACTIVATED_UPPERCASE_LETTER) != 0; + public boolean isShiftedLetterActivated() { + return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0; } // TODO: Get rid of this method. @@ -542,10 +559,6 @@ public class Key { mPressed = false; } - public void setHighlightOn(boolean highlightOn) { - mHighlightOn = highlightOn; - } - public boolean isEnabled() { return mEnabled; } @@ -639,21 +652,17 @@ public class Key { * @see android.graphics.drawable.StateListDrawable#setState(int[]) */ public int[] getCurrentDrawableState() { - final boolean pressed = mPressed; - switch (mBackgroundType) { case BACKGROUND_TYPE_FUNCTIONAL: - return pressed ? KEY_STATE_FUNCTIONAL_PRESSED : KEY_STATE_FUNCTIONAL_NORMAL; + return mPressed ? KEY_STATE_FUNCTIONAL_PRESSED : KEY_STATE_FUNCTIONAL_NORMAL; case BACKGROUND_TYPE_ACTION: - return pressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL; - case BACKGROUND_TYPE_STICKY: - if (mHighlightOn) { - return pressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON; - } else { - return pressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF; - } + return mPressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL; + case BACKGROUND_TYPE_STICKY_OFF: + return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF; + case BACKGROUND_TYPE_STICKY_ON: + return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON; default: /* BACKGROUND_TYPE_NORMAL */ - return pressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL; + return mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL; } } |
