From 4112dc05002d7a880e558418639cf25c4bd02a5a Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" <takaoka@google.com> Date: Sun, 18 Dec 2011 08:13:36 +0900 Subject: [PATCH] Move spacebar drawing code from LatinKeyboard to LatinKeyboardView Also this change moves LatinKeyboard attributes, autoCorrectionSpacebarLedEnabled, autoCorrectionSpacebarLedIcon, spacebarTextRatio, spacebarTextColor, and spacebarTextShadowColor to LatinKeyboardView. Change-Id: I7cc27ce1fc550e9f620a9ed0fbe4b8172902d5a1 --- java/res/values/attrs.xml | 16 +- java/res/values/styles.xml | 51 ++-- java/res/values/themes-basic-highcontrast.xml | 1 - java/res/values/themes-basic.xml | 1 - java/res/values/themes-gingerbread.xml | 1 - java/res/values/themes-ics.xml | 1 - java/res/values/themes-stone-bold.xml | 1 - java/res/values/themes-stone.xml | 1 - .../keyboard/KeyboardSwitcher.java | 26 +-- .../inputmethod/keyboard/LatinKeyboard.java | 213 +---------------- .../keyboard/LatinKeyboardView.java | 220 +++++++++++++++++- .../android/inputmethod/latin/LatinIME.java | 8 +- 12 files changed, 261 insertions(+), 279 deletions(-) diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index cddf513a13..c37c582742 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -124,6 +124,12 @@ </declare-styleable> <declare-styleable name="LatinKeyboardView"> + <attr name="autoCorrectionSpacebarLedEnabled" format="boolean" /> + <attr name="autoCorrectionSpacebarLedIcon" format="reference" /> + <!-- Size of the text for spacebar language label, in the proportion of key height. --> + <attr name="spacebarTextRatio" format="fraction" /> + <attr name="spacebarTextColor" format="color" /> + <attr name="spacebarTextShadowColor" format="color" /> </declare-styleable> <declare-styleable name="SuggestionsView"> @@ -327,16 +333,6 @@ <attr name="parentStyle" format="string" /> </declare-styleable> - <!-- TODO: Move these attributes to LatinKeyboardView --> - <declare-styleable name="LatinKeyboard"> - <attr name="autoCorrectionSpacebarLedEnabled" format="boolean" /> - <attr name="autoCorrectionSpacebarLedIcon" format="reference" /> - <!-- Size of the text for spacebar language label, in the proportion of key height. --> - <attr name="spacebarTextRatio" format="fraction" /> - <attr name="spacebarTextColor" format="color" /> - <attr name="spacebarTextShadowColor" format="color" /> - </declare-styleable> - <declare-styleable name="KeyboardSet"> <!-- Locale of the keyboard layouts --> <attr name="keyboardLocale" format="string" /> diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index f77586559c..d4460c93dd 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -31,13 +31,6 @@ <item name="verticalGap">@fraction/key_bottom_gap</item> <item name="maxMoreKeysColumn">@integer/config_max_more_keys_column</item> </style> - <style name="LatinKeyboard"> - <item name="autoCorrectionSpacebarLedEnabled">true</item> - <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item> - <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item> - <item name="spacebarTextColor">#FFC0C0C0</item> - <item name="spacebarTextShadowColor">#80000000</item> - </style> <style name="KeyboardView"> <item name="android:background">@drawable/keyboard_background</item> <item name="keyBackground">@drawable/btn_keyboard_key</item> @@ -75,6 +68,11 @@ <style name="LatinKeyboardView" parent="KeyboardView"> + <item name="autoCorrectionSpacebarLedEnabled">true</item> + <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item> + <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item> + <item name="spacebarTextColor">#FFC0C0C0</item> + <item name="spacebarTextShadowColor">#80000000</item> </style> <style name="MiniKeyboard" @@ -143,6 +141,11 @@ name="LatinKeyboardView.HighContrast" parent="KeyboardView.HighContrast" > + <item name="autoCorrectionSpacebarLedEnabled">true</item> + <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item> + <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item> + <item name="spacebarTextColor">#FFC0C0C0</item> + <item name="spacebarTextShadowColor">#80000000</item> </style> <!-- Theme "Stone" --> <style @@ -156,13 +159,6 @@ <item name="horizontalGap">@fraction/key_horizontal_gap_stone</item> <item name="verticalGap">@fraction/key_bottom_gap_stone</item> </style> - <style - name="LatinKeyboard.Stone" - parent="LatinKeyboard" - > - <item name="spacebarTextColor">#FF000000</item> - <item name="spacebarTextShadowColor">#D0FFFFFF</item> - </style> <style name="KeyboardView.Stone" parent="KeyboardView" @@ -180,6 +176,11 @@ name="LatinKeyboardView.Stone" parent="KeyboardView.Stone" > + <item name="autoCorrectionSpacebarLedEnabled">true</item> + <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item> + <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item> + <item name="spacebarTextColor">#FF000000</item> + <item name="spacebarTextShadowColor">#D0FFFFFF</item> </style> <style name="MiniKeyboard.Stone" @@ -214,6 +215,11 @@ name="LatinKeyboardView.Stone.Bold" parent="KeyboardView.Stone.Bold" > + <item name="autoCorrectionSpacebarLedEnabled">true</item> + <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item> + <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item> + <item name="spacebarTextColor">#FF000000</item> + <item name="spacebarTextShadowColor">#D0FFFFFF</item> </style> <!-- Theme "Gingerbread" --> <style @@ -237,6 +243,11 @@ name="LatinKeyboardView.Gingerbread" parent="KeyboardView.Gingerbread" > + <item name="autoCorrectionSpacebarLedEnabled">true</item> + <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led</item> + <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item> + <item name="spacebarTextColor">#FFC0C0C0</item> + <item name="spacebarTextShadowColor">#80000000</item> </style> <style name="MiniKeyboard.Gingerbread" @@ -264,13 +275,6 @@ <item name="verticalGap">@fraction/key_bottom_gap_ics</item> <item name="touchPositionCorrectionData">@array/touch_position_correction_data_ice_cream_sandwich</item> </style> - <style - name="LatinKeyboard.IceCreamSandwich" - parent="LatinKeyboard" - > - <item name="autoCorrectionSpacebarLedEnabled">false</item> - <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item> - </style> <style name="KeyboardView.IceCreamSandwich" parent="KeyboardView" @@ -298,6 +302,11 @@ name="LatinKeyboardView.IceCreamSandwich" parent="KeyboardView.IceCreamSandwich" > + <item name="autoCorrectionSpacebarLedEnabled">false</item> + <item name="autoCorrectionSpacebarLedIcon">@drawable/sym_keyboard_space_led_holo</item> + <item name="spacebarTextRatio">@fraction/spacebar_text_ratio</item> + <item name="spacebarTextColor">#FFC0C0C0</item> + <item name="spacebarTextShadowColor">#80000000</item> </style> <style name="MiniKeyboard.IceCreamSandwich" diff --git a/java/res/values/themes-basic-highcontrast.xml b/java/res/values/themes-basic-highcontrast.xml index a1b917057d..0062b28372 100644 --- a/java/res/values/themes-basic-highcontrast.xml +++ b/java/res/values/themes-basic-highcontrast.xml @@ -17,7 +17,6 @@ <resources> <style name="KeyboardTheme.HighContrast" parent="KeyboardIcons"> <item name="keyboardStyle">@style/Keyboard.HighContrast</item> - <item name="latinKeyboardStyle">@style/LatinKeyboard</item> <item name="keyboardViewStyle">@style/KeyboardView.HighContrast</item> <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.HighContrast</item> <item name="miniKeyboardStyle">@style/MiniKeyboard</item> diff --git a/java/res/values/themes-basic.xml b/java/res/values/themes-basic.xml index 1c2db16481..0786e08fc5 100644 --- a/java/res/values/themes-basic.xml +++ b/java/res/values/themes-basic.xml @@ -17,7 +17,6 @@ <resources> <style name="KeyboardTheme" parent="KeyboardIcons"> <item name="keyboardStyle">@style/Keyboard</item> - <item name="latinKeyboardStyle">@style/LatinKeyboard</item> <item name="keyboardViewStyle">@style/KeyboardView</item> <item name="latinKeyboardViewStyle">@style/LatinKeyboardView</item> <item name="miniKeyboardStyle">@style/MiniKeyboard</item> diff --git a/java/res/values/themes-gingerbread.xml b/java/res/values/themes-gingerbread.xml index 2af3da12e5..44338d821e 100644 --- a/java/res/values/themes-gingerbread.xml +++ b/java/res/values/themes-gingerbread.xml @@ -17,7 +17,6 @@ <resources> <style name="KeyboardTheme.Gingerbread" parent="KeyboardIcons"> <item name="keyboardStyle">@style/Keyboard.Gingerbread</item> - <item name="latinKeyboardStyle">@style/LatinKeyboard</item> <item name="keyboardViewStyle">@style/KeyboardView.Gingerbread</item> <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.Gingerbread</item> <item name="miniKeyboardStyle">@style/MiniKeyboard.Gingerbread</item> diff --git a/java/res/values/themes-ics.xml b/java/res/values/themes-ics.xml index b7898414e8..dbc8f32e3e 100644 --- a/java/res/values/themes-ics.xml +++ b/java/res/values/themes-ics.xml @@ -17,7 +17,6 @@ <resources> <style name="KeyboardTheme.IceCreamSandwich" parent="KeyboardIcons.IceCreamSandwich"> <item name="keyboardStyle">@style/Keyboard.IceCreamSandwich</item> - <item name="latinKeyboardStyle">@style/LatinKeyboard.IceCreamSandwich</item> <item name="keyboardViewStyle">@style/KeyboardView.IceCreamSandwich</item> <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.IceCreamSandwich</item> <item name="miniKeyboardStyle">@style/MiniKeyboard.IceCreamSandwich</item> diff --git a/java/res/values/themes-stone-bold.xml b/java/res/values/themes-stone-bold.xml index cf2cb91002..60f130d59b 100644 --- a/java/res/values/themes-stone-bold.xml +++ b/java/res/values/themes-stone-bold.xml @@ -17,7 +17,6 @@ <resources> <style name="KeyboardTheme.Stone.Bold" parent="KeyboardIcons.Black"> <item name="keyboardStyle">@style/Keyboard.Stone.Bold</item> - <item name="latinKeyboardStyle">@style/LatinKeyboard.Stone</item> <item name="keyboardViewStyle">@style/KeyboardView.Stone.Bold</item> <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.Stone.Bold</item> <item name="miniKeyboardStyle">@style/MiniKeyboard.Stone</item> diff --git a/java/res/values/themes-stone.xml b/java/res/values/themes-stone.xml index be0755f9ab..9aaca3a6c9 100644 --- a/java/res/values/themes-stone.xml +++ b/java/res/values/themes-stone.xml @@ -17,7 +17,6 @@ <resources> <style name="KeyboardTheme.Stone" parent="KeyboardIcons.Black"> <item name="keyboardStyle">@style/Keyboard.Stone</item> - <item name="latinKeyboardStyle">@style/LatinKeyboard.Stone</item> <item name="keyboardViewStyle">@style/KeyboardView.Stone</item> <item name="latinKeyboardViewStyle">@style/LatinKeyboardView.Stone</item> <item name="miniKeyboardStyle">@style/MiniKeyboard.Stone</item> diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 35734fb875..1625d2233c 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -157,20 +157,16 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, mKeyboardView.setKeyPreviewPopupEnabled( SettingsValues.isKeyPreviewPopupEnabled(mPrefs, mResources), SettingsValues.getKeyPreviewPopupDismissDelay(mPrefs, mResources)); + mKeyboardView.updateAutoCorrectionState(mIsAutoCorrectionActive); + // If the cached keyboard had been switched to another keyboard while the language was + // displayed on its spacebar, it might have had arbitrary text fade factor. In such + // case, we should reset the text fade factor. It is also applicable to shortcut key. + mKeyboardView.updateSpacebar(0.0f, + mSubtypeSwitcher.needsToDisplayLanguage(keyboard.mId.mLocale)); mKeyboardView.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady()); + updateShiftState(); final boolean localeChanged = (oldKeyboard == null) || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); - if (keyboard instanceof LatinKeyboard) { - final LatinKeyboard latinKeyboard = (LatinKeyboard)keyboard; - latinKeyboard.updateAutoCorrectionState(mIsAutoCorrectionActive); - // If the cached keyboard had been switched to another keyboard while the language was - // displayed on its spacebar, it might have had arbitrary text fade factor. In such - // case, we should reset the text fade factor. It is also applicable to shortcut key. - mKeyboardView.updateSpacebar(); - latinKeyboard.updateSpacebarLanguage(0.0f, - mSubtypeSwitcher.needsToDisplayLanguage(latinKeyboard.mId.mLocale)); - } - updateShiftState(); mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged); } @@ -419,12 +415,8 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, public void onAutoCorrectionStateChanged(boolean isAutoCorrection) { if (mIsAutoCorrectionActive != isAutoCorrection) { mIsAutoCorrectionActive = isAutoCorrection; - final LatinKeyboard keyboard = getLatinKeyboard(); - if (keyboard != null && keyboard.needsAutoCorrectionSpacebarLed()) { - final Key invalidatedKey = keyboard.updateAutoCorrectionState(isAutoCorrection); - final LatinKeyboardView keyboardView = getKeyboardView(); - if (keyboardView != null) - keyboardView.invalidateKey(invalidatedKey); + if (mKeyboardView != null) { + mKeyboardView.updateAutoCorrectionState(isAutoCorrection); } } } diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index 30c07bed91..54118f4d86 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -17,77 +17,14 @@ package com.android.inputmethod.keyboard; import android.content.Context; -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.drawable.Drawable; import com.android.inputmethod.keyboard.internal.KeyboardBuilder; import com.android.inputmethod.keyboard.internal.KeyboardParams; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.Utils; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Locale; // TODO: We should remove this class public class LatinKeyboard extends Keyboard { - private static final int SPACE_LED_LENGTH_PERCENT = 80; - - private final Resources mRes; - - /* Space key and its icons, drawables and colors. */ - private final Key mSpaceKey; - private final Drawable mSpaceIcon; - private final boolean mAutoCorrectionSpacebarLedEnabled; - private final Drawable mAutoCorrectionSpacebarLedIcon; - private final float mSpacebarTextSize; - private final int mSpacebarTextColor; - private final int mSpacebarTextShadowColor; - private final HashMap<Integer, BitmapDrawable> mSpaceDrawableCache = - new HashMap<Integer, BitmapDrawable>(); - - private boolean mAutoCorrectionSpacebarLedOn; - private boolean mNeedsToDisplayLanguage; - 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; - // 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 LatinKeyboard(Context context, KeyboardParams params) { + private LatinKeyboard(KeyboardParams params) { super(params); - mRes = context.getResources(); - - // The index of space key is available only after Keyboard constructor has finished. - mSpaceKey = getKey(CODE_SPACE); - mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null; - - // TODO: Move these to LatinKeyboardView attributes. - final TypedArray a = context.obtainStyledAttributes( - null, R.styleable.LatinKeyboard, R.attr.latinKeyboardStyle, R.style.LatinKeyboard); - mAutoCorrectionSpacebarLedEnabled = a.getBoolean( - R.styleable.LatinKeyboard_autoCorrectionSpacebarLedEnabled, false); - mAutoCorrectionSpacebarLedIcon = a.getDrawable( - R.styleable.LatinKeyboard_autoCorrectionSpacebarLedIcon); - final float spacebarTextRatio = a.getFraction(R.styleable.LatinKeyboard_spacebarTextRatio, - 1000, 1000, 1) / 1000.0f; - final int keyHeight = mMostCommonKeyHeight - mVerticalGap; - mSpacebarTextSize = keyHeight * spacebarTextRatio; - mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboard_spacebarTextColor, 0); - mSpacebarTextShadowColor = a.getColor( - R.styleable.LatinKeyboard_spacebarTextShadowColor, 0); - a.recycle(); } public static class Builder extends KeyboardBuilder<KeyboardParams> { @@ -103,154 +40,8 @@ public class LatinKeyboard extends Keyboard { @Override public LatinKeyboard build() { - return new LatinKeyboard(mContext, mParams); - } - } - - // TODO: Move this drawing method to LatinKeyboardView. - // TODO: Use Key.keyLabel to draw language name of spacebar. - public Key updateSpacebarLanguage(float fadeFactor, boolean needsToDisplayLanguage) { - mSpacebarTextFadeFactor = fadeFactor; - mNeedsToDisplayLanguage = needsToDisplayLanguage; - updateSpacebarIcon(); - return mSpaceKey; - } - - 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)); - return newColor; - } - - // TODO: Get rid of this method - public boolean needsAutoCorrectionSpacebarLed() { - return mAutoCorrectionSpacebarLedEnabled; - } - - // TODO: Move this drawing method to LatinKeyboardView. - /** - * @return a key which should be invalidated. - */ - public Key updateAutoCorrectionState(boolean isAutoCorrection) { - mAutoCorrectionSpacebarLedOn = isAutoCorrection; - updateSpacebarIcon(); - return mSpaceKey; - } - - private void updateSpacebarIcon() { - if (mSpaceKey == null) return; - if (mNeedsToDisplayLanguage) { - mSpaceKey.setIcon(getSpaceDrawable(mId.mLocale)); - } else if (mAutoCorrectionSpacebarLedOn) { - mSpaceKey.setIcon(getSpaceDrawable(null)); - } else { - mSpaceKey.setIcon(mSpaceIcon); - } - } - - // Compute width of text with specified text size using paint. - private static int getTextWidth(Paint paint, String text, float textSize, Rect bounds) { - paint.setTextSize(textSize); - paint.getTextBounds(text, 0, text.length(), bounds); - return bounds.width(); - } - - // Layout local language name and left and right arrow on spacebar. - private static String layoutSpacebar(Paint paint, Locale locale, int width, - float origTextSize) { - final Rect bounds = new Rect(); - - // Estimate appropriate language name text size to fit in maxTextWidth. - String language = Utils.getFullDisplayName(locale, true); - int textWidth = getTextWidth(paint, language, origTextSize, bounds); - // 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); - // 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); - - final boolean useShortName; - if (useMiddleName) { - language = Utils.getMiddleDisplayLanguage(locale); - textWidth = getTextWidth(paint, language, origTextSize, bounds); - textSize = origTextSize * Math.min(width / textWidth, 1.0f); - useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) - || (textWidth > width); - } else { - useShortName = false; - } - - if (useShortName) { - language = Utils.getShortDisplayLanguage(locale); - textWidth = getTextWidth(paint, language, origTextSize, bounds); - textSize = origTextSize * Math.min(width / textWidth, 1.0f); - } - paint.setTextSize(textSize); - - return language; - } - - private BitmapDrawable getSpaceDrawable(Locale locale) { - final Integer hashCode = Arrays.hashCode( - new Object[] { locale, mAutoCorrectionSpacebarLedOn, mSpacebarTextFadeFactor }); - final BitmapDrawable cached = mSpaceDrawableCache.get(hashCode); - if (cached != null) { - return cached; - } - final BitmapDrawable drawable = new BitmapDrawable(mRes, drawSpacebar( - locale, mAutoCorrectionSpacebarLedOn, mSpacebarTextFadeFactor)); - mSpaceDrawableCache.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); - - // 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); - - // Draw language text with shadow - // In case there is no space icon, we will place the language text at the center of - // spacebar. - final float descent = paint.descent(); - final float textHeight = -paint.ascent() + descent; - final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE - : height / 2 + textHeight / 2; - paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, textFadeFactor)); - canvas.drawText(language, width / 2, baseline - descent - 1, paint); - paint.setColor(getSpacebarTextColor(mSpacebarTextColor, textFadeFactor)); - canvas.drawText(language, width / 2, baseline - descent, paint); - } - - // Draw the spacebar icon at the bottom - if (isAutoCorrection) { - 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); - } 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); + return new LatinKeyboard(mParams); } - return buffer; } @Override diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index ccea00f43d..10a544c21d 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -19,8 +19,16 @@ package com.android.inputmethod.keyboard; 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.drawable.Drawable; import android.os.Message; import android.text.TextUtils; import android.util.AttributeSet; @@ -47,6 +55,9 @@ 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; /** @@ -62,9 +73,30 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true; - // For drawing spacebar. + /* Space key and its icons, drawables and colors. */ + private Key mSpaceKey; + private Drawable mSpaceIcon; private final boolean mIsSpacebarTriggeringPopupByLongPress; - private boolean mMultipleEnabledIMEsOrSubtypes; + private static final int SPACE_LED_LENGTH_PERCENT = 80; + private final boolean mAutoCorrectionSpacebarLedEnabled; + private final Drawable mAutoCorrectionSpacebarLedIcon; + 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; + // 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; @@ -257,6 +289,19 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke final int longPressSpaceKeyTimeout = res.getInteger(R.integer.config_long_press_space_key_timeout); mIsSpacebarTriggeringPopupByLongPress = (longPressSpaceKeyTimeout > 0); + + final TypedArray a = context.obtainStyledAttributes( + attrs, R.styleable.LatinKeyboardView, defStyle, R.style.LatinKeyboardView); + mAutoCorrectionSpacebarLedEnabled = a.getBoolean( + R.styleable.LatinKeyboardView_autoCorrectionSpacebarLedEnabled, false); + mAutoCorrectionSpacebarLedIcon = a.getDrawable( + R.styleable.LatinKeyboardView_autoCorrectionSpacebarLedIcon); + mSpacebarTextRatio = a.getFraction(R.styleable.LatinKeyboardView_spacebarTextRatio, + 1000, 1000, 1) / 1000.0f; + mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboardView_spacebarTextColor, 0); + mSpacebarTextShadowColor = a.getColor( + R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0); + a.recycle(); } public void startIgnoringDoubleTap() { @@ -311,6 +356,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke PointerTracker.setKeyDetector(mKeyDetector); mTouchScreenRegulator.setKeyboard(keyboard); mMoreKeysPanelCache.clear(); + + mSpaceKey = keyboard.getKey(Keyboard.CODE_SPACE); + mSpaceIcon = keyboard.mIconsSet.getIcon(KeyboardIconsSet.ICON_SPACE_KEY); + final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; + mSpacebarTextSize = keyHeight * mSpacebarTextRatio; + mSpacebarLocale = keyboard.mId.mLocale; + clearSpacebarDrawableCache(); } /** @@ -708,9 +760,18 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke invalidateKey(shortcutKey); } - public void updateSpacebar() { - mMultipleEnabledIMEsOrSubtypes = Utils.hasMultipleEnabledIMEsOrSubtypes( - true /* include aux subtypes */); + 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); } @Override @@ -718,10 +779,151 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke KeyDrawParams params) { super.onDrawKeyTopVisuals(key, canvas, paint, params); - // Whether space key needs to show the "..." popup hint for special purposes - if (key.mCode == Keyboard.CODE_SPACE && mIsSpacebarTriggeringPopupByLongPress - && mMultipleEnabledIMEsOrSubtypes) { - super.drawKeyPopupHint(key, canvas, paint, params); + if (key.mCode == Keyboard.CODE_SPACE) { + // 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); + } } } + + // 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)); + return newColor; + } + + // Compute width of text with specified text size using paint. + private static int getTextWidth(Paint paint, String text, float textSize, Rect bounds) { + paint.setTextSize(textSize); + paint.getTextBounds(text, 0, text.length(), bounds); + return bounds.width(); + } + + // Layout local language name and left and right arrow on spacebar. + private static String layoutSpacebar(Paint paint, Locale locale, int width, + float origTextSize) { + final Rect bounds = new Rect(); + + // Estimate appropriate language name text size to fit in maxTextWidth. + String language = Utils.getFullDisplayName(locale, true); + int textWidth = getTextWidth(paint, language, origTextSize, bounds); + // 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); + // 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); + + final boolean useShortName; + if (useMiddleName) { + language = Utils.getMiddleDisplayLanguage(locale); + textWidth = getTextWidth(paint, language, origTextSize, bounds); + textSize = origTextSize * Math.min(width / textWidth, 1.0f); + useShortName = (textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME) + || (textWidth > width); + } else { + useShortName = false; + } + + if (useShortName) { + language = Utils.getShortDisplayLanguage(locale); + textWidth = getTextWidth(paint, language, origTextSize, bounds); + textSize = origTextSize * Math.min(width / textWidth, 1.0f); + } + paint.setTextSize(textSize); + + 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); + + // 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); + + // Draw language text with shadow + // In case there is no space icon, we will place the language text at the center of + // spacebar. + final float descent = paint.descent(); + final float textHeight = -paint.ascent() + descent; + final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE + : height / 2 + textHeight / 2; + paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, textFadeFactor)); + canvas.drawText(language, width / 2, baseline - descent - 1, paint); + paint.setColor(getSpacebarTextColor(mSpacebarTextColor, textFadeFactor)); + canvas.drawText(language, width / 2, baseline - descent, paint); + } + + // Draw the spacebar icon at the bottom + if (isAutoCorrection) { + 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); + } 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); + } + return buffer; + } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 64bd506f57..c868f14fc6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -344,11 +344,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar if (inputView == null) return; final Keyboard keyboard = inputView.getKeyboard(); if (keyboard instanceof LatinKeyboard && keyboard == oldKeyboard) { - inputView.updateSpacebar(); - final Key updatedKey = ((LatinKeyboard)keyboard).updateSpacebarLanguage( - fadeFactor, - SubtypeSwitcher.getInstance().needsToDisplayLanguage(keyboard.mId.mLocale)); - inputView.invalidateKey(updatedKey); + inputView.updateSpacebar(fadeFactor, + SubtypeSwitcher.getInstance().needsToDisplayLanguage( + keyboard.mId.mLocale)); } } -- GitLab