diff options
Diffstat (limited to 'java/src')
9 files changed, 199 insertions, 173 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index b3c5ed75d..9c495fd5f 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -71,14 +71,16 @@ 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; - // TODO: These icon references could be int (icon attribute id) /** Icon to display instead of a label. Icon takes precedence over a label */ + private final int mIconAttrId; + // TODO: Remove this variable. private Drawable mIcon; /** Icon for disabled state */ - private Drawable mDisabledIcon; + private final int mDisabledIconAttrId; /** Preview version of the icon, for the preview popup */ - public final Drawable mPreviewIcon; + public final int mPreviewIconAttrId; /** Width of the key, not including the gap */ public final int mWidth; @@ -204,9 +206,10 @@ public class Key { mOutputText = outputText; mCode = code; mAltCode = Keyboard.CODE_UNSPECIFIED; + mIconAttrId = KeyboardIconsSet.ATTR_UNDEFINED; mIcon = icon; - mDisabledIcon = null; - mPreviewIcon = null; + mDisabledIconAttrId = KeyboardIconsSet.ATTR_UNDEFINED; + mPreviewIconAttrId = KeyboardIconsSet.ATTR_UNDEFINED; // Horizontal gap is divided equally to both sides of the key. mX = x + mHorizontalGap / 2; mY = y; @@ -260,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); @@ -282,24 +272,47 @@ public class Key { R.styleable.Keyboard_Key_visualInsetsLeft, params.mBaseWidth, 0); mVisualInsetsRight = (int) Keyboard.Builder.getDimensionOrFraction(keyAttr, R.styleable.Keyboard_Key_visualInsetsRight, params.mBaseWidth, 0); - final int previewIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr, + mPreviewIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr, R.styleable.Keyboard_Key_keyIconPreview, KeyboardIconsSet.ICON_UNDEFINED)); - mPreviewIcon = iconsSet.getIconByAttrId(previewIconAttrId); - final int iconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr, + mIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr, R.styleable.Keyboard_Key_keyIcon, KeyboardIconsSet.ICON_UNDEFINED)); - mIcon = iconsSet.getIconByAttrId(iconAttrId); - final int disabledIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr, + mIcon = iconsSet.getIconByAttrId(mIconAttrId); + mDisabledIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled, KeyboardIconsSet.ICON_UNDEFINED)); - mDisabledIcon = iconsSet.getIconByAttrId(disabledIconAttrId); - mHintLabel = style.getString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel); - mLabel = style.getString(keyAttr, R.styleable.Keyboard_Key_keyLabel); 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, @@ -328,13 +364,15 @@ public class Key { key.mCode, key.mLabel, key.mHintLabel, + key.mIconAttrId, // Key can be distinguishable without the following members. // key.mAltCode, // key.mOutputText, // key.mActionFlags, // key.mLabelFlags, // key.mIcon, - // key.mPreviewIcon, + // key.mDisabledIconAttrId, + // key.mPreviewIconAttrId, // key.mBackgroundType, // key.mHorizontalGap, // key.mVerticalGap, @@ -471,8 +509,9 @@ public class Key { return (mLabelFlags & LABEL_FLAGS_AUTO_X_SCALE) != 0; } - public Drawable getIcon() { - return mEnabled ? mIcon : mDisabledIcon; + // TODO: Get rid of this method. + public Drawable getIcon(KeyboardIconsSet iconSet) { + return mEnabled ? mIcon : iconSet.getIconByAttrId(mDisabledIconAttrId); } // TODO: Get rid of this method. diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 8c386dad2..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); @@ -1034,6 +1041,9 @@ public class Keyboard { final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser), R.styleable.Keyboard_Case); try { + final boolean keyboardSetElementMatched = matchTypedValue(a, + R.styleable.Keyboard_Case_keyboardSetElement, id.mElementId, + KeyboardId.elementIdToName(id.mElementId)); final boolean modeMatched = matchTypedValue(a, R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode)); final boolean navigateActionMatched = matchBoolean(a, @@ -1062,13 +1072,15 @@ public class Keyboard { R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage()); final boolean countryCodeMatched = matchString(a, R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry()); - final boolean selected = modeMatched && navigateActionMatched - && passwordInputMatched && hasSettingsKeyMatched && f2KeyModeMatched - && clobberSettingsKeyMatched && shortcutKeyEnabledMatched - && hasShortcutKeyMatched && imeActionMatched && localeCodeMatched - && languageCodeMatched && countryCodeMatched; - - if (DEBUG) Log.d(TAG, String.format("<%s%s%s%s%s%s%s%s%s%s%s%s%s> %s", TAG_CASE, + final boolean selected = keyboardSetElementMatched && modeMatched + && navigateActionMatched && passwordInputMatched && hasSettingsKeyMatched + && f2KeyModeMatched && clobberSettingsKeyMatched + && shortcutKeyEnabledMatched && hasShortcutKeyMatched && imeActionMatched + && localeCodeMatched && languageCodeMatched && countryCodeMatched; + + if (DEBUG) Log.d(TAG, String.format("<%s%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"), booleanAttr(a, R.styleable.Keyboard_Case_navigateAction, "navigateAction"), booleanAttr(a, R.styleable.Keyboard_Case_passwordInput, "passwordInput"), 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; } } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 732c8afb0..afcf51059 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -39,6 +39,7 @@ import android.widget.RelativeLayout; import android.widget.TextView; import com.android.inputmethod.compat.FrameLayoutCompatUtils; +import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; @@ -552,7 +553,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } // Draw key label. - final Drawable icon = key.getIcon(); + final Drawable icon = key.getIcon(mKeyboard.mIconsSet); float positionX = centerX; if (key.mLabel != null) { // Switch the character to uppercase if shift is pressed @@ -898,9 +899,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } previewText.setText(mKeyboard.adjustLabelCase(key.mLabel)); } else { - final Drawable previewIcon = key.mPreviewIcon; + final Drawable previewIcon = mKeyboard.mIconsSet.getIconByAttrId( + key.mPreviewIconAttrId); previewText.setCompoundDrawables(null, null, null, - previewIcon != null ? previewIcon : key.getIcon()); + previewIcon != null ? previewIcon : key.getIcon(mKeyboard.mIconsSet)); previewText.setText(null); } previewText.setBackgroundDrawable(params.mPreviewBackground); diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 6dcc1dc36..f5b282df3 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -20,14 +20,11 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.content.res.TypedArray; -import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.graphics.drawable.BitmapDrawable; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Message; import android.text.TextUtils; @@ -54,8 +51,6 @@ import com.android.inputmethod.latin.StaticInnerHandlerWrapper; import com.android.inputmethod.latin.Utils; import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils; -import java.util.Arrays; -import java.util.HashMap; import java.util.Locale; import java.util.WeakHashMap; @@ -72,38 +67,33 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true; - /* Space key and its icons, drawables and colors. */ + // TODO: Kill process when the usability study mode was changed. + private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy; + + /** Listener for {@link KeyboardActionListener}. */ + private KeyboardActionListener mKeyboardActionListener; + + /* Space key and its icons */ private Key mSpaceKey; private Drawable mSpaceIcon; - private final boolean mIsSpacebarTriggeringPopupByLongPress; - private static final int SPACE_LED_LENGTH_PERCENT = 80; - private final boolean mAutoCorrectionSpacebarLedEnabled; - private final Drawable mAutoCorrectionSpacebarLedIcon; + // Stuff to draw language name on spacebar. + private boolean mNeedsToDisplayLanguage; + private Locale mSpacebarLocale; + private float mSpacebarTextFadeFactor = 0.0f; private final float mSpacebarTextRatio; private float mSpacebarTextSize; private final int mSpacebarTextColor; private final int mSpacebarTextShadowColor; - private final HashMap<Integer, BitmapDrawable> mSpacebarDrawableCache = - new HashMap<Integer, BitmapDrawable>(); - - private boolean mAutoCorrectionSpacebarLedOn; - private boolean mNeedsToDisplayLanguage; - private Locale mSpacebarLocale; - private float mSpacebarTextFadeFactor = 0.0f; - // Height in space key the language name will be drawn. (proportional to space key height) - public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; + private static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; // If the full language name needs to be smaller than this value to be drawn on space key, // its short language name will be used instead. private static final float MINIMUM_SCALE_OF_LANGUAGE_NAME = 0.8f; - - private final SuddenJumpingTouchEventHandler mTouchScreenRegulator; - - // Timing constants - private final int mKeyRepeatInterval; - - // TODO: Kill process when the usability study mode was changed. - private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy; + // Stuff to draw auto correction LED on spacebar. + private boolean mAutoCorrectionSpacebarLedOn; + private final boolean mAutoCorrectionSpacebarLedEnabled; + private final Drawable mAutoCorrectionSpacebarLedIcon; + private static final int SPACE_LED_LENGTH_PERCENT = 80; // Mini keyboard private PopupWindow mMoreKeysWindow; @@ -111,17 +101,16 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private int mMoreKeysPanelPointerTrackerId; private final WeakHashMap<Key, MoreKeysPanel> mMoreKeysPanelCache = new WeakHashMap<Key, MoreKeysPanel>(); + private final boolean mConfigShowMiniKeyboardAtTouchedPoint; - /** Listener for {@link KeyboardActionListener}. */ - private KeyboardActionListener mKeyboardActionListener; + private final boolean mIsSpacebarTriggeringPopupByLongPress; + private final SuddenJumpingTouchEventHandler mTouchScreenRegulator; + protected KeyDetector mKeyDetector; private boolean mHasDistinctMultitouch; private int mOldPointerCount = 1; private Key mOldKey; - private final boolean mConfigShowMiniKeyboardAtTouchedPoint; - protected KeyDetector mKeyDetector; - // To detect double tap. protected GestureDetector mGestureDetector; @@ -134,10 +123,14 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private static final int MSG_IGNORE_DOUBLE_TAP = 3; private static final int MSG_KEY_TYPED = 4; + private final int mKeyRepeatInterval; private boolean mInKeyRepeat; public KeyTimerHandler(LatinKeyboardView outerInstance) { super(outerInstance); + // TODO: This should be the attribute of LatinKeyboardView. + final Resources res = outerInstance.getContext().getResources(); + mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval); } @Override @@ -147,7 +140,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke switch (msg.what) { case MSG_REPEAT_KEY: tracker.onRepeatKey(tracker.getKey()); - startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, tracker); + startKeyRepeatTimer(mKeyRepeatInterval, tracker); break; case MSG_LONGPRESS_KEY: keyboardView.openMiniKeyboardIfRequired(tracker.getKey(), tracker); @@ -213,7 +206,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } } - private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener { + class DoubleTapListener extends GestureDetector.SimpleOnGestureListener { private boolean mProcessingShiftDoubleTapEvent = false; @Override @@ -270,8 +263,10 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this); final Resources res = getResources(); + // TODO: This should be the attribute of LatinKeyboardView. mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean( R.bool.config_show_mini_keyboard_at_touched_point); + // TODO: This should be the attribute of LatinKeyboardView. final float keyHysteresisDistance = res.getDimension(R.dimen.key_hysteresis_distance); mKeyDetector = new KeyDetector(keyHysteresisDistance); @@ -282,10 +277,10 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke mHasDistinctMultitouch = context.getPackageManager() .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT); - mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval); PointerTracker.init(mHasDistinctMultitouch, getContext()); + // TODO: This should be the attribute of LatinKeyboardView. final int longPressSpaceKeyTimeout = res.getInteger(R.integer.config_long_press_space_key_timeout); mIsSpacebarTriggeringPopupByLongPress = (longPressSpaceKeyTimeout > 0); @@ -362,7 +357,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; mSpacebarTextSize = keyHeight * mSpacebarTextRatio; mSpacebarLocale = keyboard.mId.mLocale; - clearSpacebarDrawableCache(); } /** @@ -759,14 +753,12 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke public void updateSpacebar(float fadeFactor, boolean needsToDisplayLanguage) { mSpacebarTextFadeFactor = fadeFactor; mNeedsToDisplayLanguage = needsToDisplayLanguage; - updateSpacebarIcon(); invalidateKey(mSpaceKey); } public void updateAutoCorrectionState(boolean isAutoCorrection) { if (!mAutoCorrectionSpacebarLedEnabled) return; mAutoCorrectionSpacebarLedOn = isAutoCorrection; - updateSpacebarIcon(); invalidateKey(mSpaceKey); } @@ -775,27 +767,16 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke super.onDrawKeyTopVisuals(key, canvas, paint, params); if (key.mCode == Keyboard.CODE_SPACE) { + drawSpacebar(key, canvas, paint); + // Whether space key needs to show the "..." popup hint for special purposes if (mIsSpacebarTriggeringPopupByLongPress && Utils.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { - super.drawKeyPopupHint(key, canvas, paint, params); + drawKeyPopupHint(key, canvas, paint, params); } } } - // TODO: Get rid of this method and draw spacebar locale and auto correction spacebar LED - // in onDrawKeyTopVisuals. - private void updateSpacebarIcon() { - if (mSpaceKey == null) return; - if (mNeedsToDisplayLanguage) { - mSpaceKey.setIcon(getSpaceDrawable(mSpacebarLocale)); - } else if (mAutoCorrectionSpacebarLedOn) { - mSpaceKey.setIcon(getSpaceDrawable(null)); - } else { - mSpaceKey.setIcon(mSpaceIcon); - } - } - private static int getSpacebarTextColor(int color, float fadeFactor) { final int newColor = Color.argb((int)(Color.alpha(color) * fadeFactor), Color.red(color), Color.green(color), Color.blue(color)); @@ -803,24 +784,23 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke } // Compute width of text with specified text size using paint. - private static int getTextWidth(Paint paint, String text, float textSize, Rect bounds) { + private int getTextWidth(Paint paint, String text, float textSize) { paint.setTextSize(textSize); - paint.getTextBounds(text, 0, text.length(), bounds); - return bounds.width(); + return (int)getLabelWidth(text, paint); } // Layout locale language name on spacebar. - private static String layoutSpacebar(Paint paint, Locale locale, int width, + private String layoutLanguageOnSpacebar(Paint paint, Locale locale, int width, float origTextSize) { - final Rect bounds = new Rect(); - + paint.setTextAlign(Align.CENTER); + paint.setTypeface(Typeface.DEFAULT); // Estimate appropriate language name text size to fit in maxTextWidth. String language = Utils.getFullDisplayName(locale, true); - int textWidth = getTextWidth(paint, language, origTextSize, bounds); + int textWidth = getTextWidth(paint, language, origTextSize); // Assuming text width and text size are proportional to each other. float textSize = origTextSize * Math.min(width / textWidth, 1.0f); // allow variable text size - textWidth = getTextWidth(paint, language, textSize, bounds); + textWidth = getTextWidth(paint, language, textSize); // If text size goes too small or text does not fit, use middle or short name final boolean useMiddleName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) || (textWidth > width); @@ -828,7 +808,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final boolean useShortName; if (useMiddleName) { language = Utils.getMiddleDisplayLanguage(locale); - textWidth = getTextWidth(paint, language, origTextSize, bounds); + textWidth = getTextWidth(paint, language, origTextSize); textSize = origTextSize * Math.min(width / textWidth, 1.0f); useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) || (textWidth > width); @@ -838,7 +818,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke if (useShortName) { language = Utils.getShortDisplayLanguage(locale); - textWidth = getTextWidth(paint, language, origTextSize, bounds); + textWidth = getTextWidth(paint, language, origTextSize); textSize = origTextSize * Math.min(width / textWidth, 1.0f); } paint.setTextSize(textSize); @@ -846,50 +826,14 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke return language; } - private Integer getSpaceDrawableKey(Locale locale) { - return Arrays.hashCode(new Object[] { - locale, - mAutoCorrectionSpacebarLedOn, - mSpacebarTextFadeFactor - }); - } - - private void clearSpacebarDrawableCache() { - for (final BitmapDrawable drawable : mSpacebarDrawableCache.values()) { - final Bitmap bitmap = drawable.getBitmap(); - bitmap.recycle(); - } - mSpacebarDrawableCache.clear(); - } - - private BitmapDrawable getSpaceDrawable(Locale locale) { - final Integer hashCode = getSpaceDrawableKey(locale); - final BitmapDrawable cached = mSpacebarDrawableCache.get(hashCode); - if (cached != null) { - return cached; - } - final BitmapDrawable drawable = new BitmapDrawable(getResources(), drawSpacebar( - locale, mAutoCorrectionSpacebarLedOn, mSpacebarTextFadeFactor)); - mSpacebarDrawableCache.put(hashCode, drawable); - return drawable; - } - - private Bitmap drawSpacebar(Locale inputLocale, boolean isAutoCorrection, - float textFadeFactor) { - final int width = mSpaceKey.mWidth; - final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight; - final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - final Canvas canvas = new Canvas(buffer); - canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + private void drawSpacebar(Key key, Canvas canvas, Paint paint) { + final int width = key.mWidth; + final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : key.mHeight; // If application locales are explicitly selected. - if (inputLocale != null) { - final Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setTextAlign(Align.CENTER); - - final String language = layoutSpacebar(paint, inputLocale, width, mSpacebarTextSize); - + if (mNeedsToDisplayLanguage) { + final String language = layoutLanguageOnSpacebar(paint, mSpacebarLocale, width, + mSpacebarTextSize); // Draw language text with shadow // In case there is no space icon, we will place the language text at the center of // spacebar. @@ -897,28 +841,25 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final float textHeight = -paint.ascent() + descent; final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE : height / 2 + textHeight / 2; - paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, textFadeFactor)); + paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor)); canvas.drawText(language, width / 2, baseline - descent - 1, paint); - paint.setColor(getSpacebarTextColor(mSpacebarTextColor, textFadeFactor)); + paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor)); canvas.drawText(language, width / 2, baseline - descent, paint); } // Draw the spacebar icon at the bottom - if (isAutoCorrection) { + if (mAutoCorrectionSpacebarLedOn) { final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100; final int iconHeight = mAutoCorrectionSpacebarLedIcon.getIntrinsicHeight(); int x = (width - iconWidth) / 2; int y = height - iconHeight; - mAutoCorrectionSpacebarLedIcon.setBounds(x, y, x + iconWidth, y + iconHeight); - mAutoCorrectionSpacebarLedIcon.draw(canvas); + drawIcon(canvas, mAutoCorrectionSpacebarLedIcon, x, y, iconWidth, iconHeight); } else if (mSpaceIcon != null) { final int iconWidth = mSpaceIcon.getIntrinsicWidth(); final int iconHeight = mSpaceIcon.getIntrinsicHeight(); int x = (width - iconWidth) / 2; int y = height - iconHeight; - mSpaceIcon.setBounds(x, y, x + iconWidth, y + iconHeight); - mSpaceIcon.draw(canvas); + drawIcon(canvas, mSpaceIcon, x, y, iconWidth, iconHeight); } - return buffer; } } diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java index 09ecbcaa0..bec6ae1cc 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java @@ -31,7 +31,7 @@ public class KeyboardIconsSet { private static final String TAG = KeyboardIconsSet.class.getSimpleName(); public static final int ICON_UNDEFINED = 0; - private static final int ATTR_UNDEFINED = 0; + public static final int ATTR_UNDEFINED = 0; private final Map<Integer, Drawable> mIcons = new HashMap<Integer, Drawable>(); diff --git a/java/src/com/android/inputmethod/latin/ComposingStateManager.java b/java/src/com/android/inputmethod/latin/ComposingStateManager.java index 8811f2023..27f509a29 100644 --- a/java/src/com/android/inputmethod/latin/ComposingStateManager.java +++ b/java/src/com/android/inputmethod/latin/ComposingStateManager.java @@ -53,6 +53,13 @@ public class ComposingStateManager { } } + public synchronized boolean isComposing() { + // TODO: use the composing flag in WordComposer instead of maintaining it + // here separately. Even better, do away with this class and manage the auto + // correction indicator in the same place as the suggestions. + return mIsComposing; + } + public synchronized boolean isAutoCorrectionIndicatorOn() { return mAutoCorrectionIndicatorOn; } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 31cbc4ee3..d59497d6a 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1702,10 +1702,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (DEBUG) { Log.d(TAG, "Flip the indicator. " + oldAutoCorrectionIndicator + " -> " + newAutoCorrectionIndicator); - if (newAutoCorrectionIndicator + if (mComposingStateManager.isComposing() && newAutoCorrectionIndicator != mComposingStateManager.isAutoCorrectionIndicatorOn()) { - throw new RuntimeException("Couldn't flip the indicator! We are not " - + "composing a word right now."); + throw new RuntimeException("Couldn't flip the indicator!"); } } final CharSequence textWithUnderline = diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java index 2bc2cfdf6..db3544987 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerProximityInfo.java @@ -22,7 +22,8 @@ import com.android.inputmethod.keyboard.ProximityInfo; import java.util.TreeMap; public class SpellCheckerProximityInfo { - final private static int NUL = KeyDetector.NOT_A_CODE; + /* public for test */ + final public static int NUL = KeyDetector.NOT_A_CODE; // This must be the same as MAX_PROXIMITY_CHARS_SIZE else it will not work inside // native code - this value is passed at creation of the binary object and reused |