Merge "Don't show spacebar preview if key preview is disabled"

This commit is contained in:
Tadashi G. Takaoka 2011-04-15 07:24:19 -07:00 committed by Android (Google) Code Review
commit 8cd0acba6d
4 changed files with 97 additions and 51 deletions

View file

@ -128,6 +128,8 @@ public class Keyboard {
/** Height of keyboard */ /** Height of keyboard */
private int mKeyboardHeight; private int mKeyboardHeight;
private int mMostCommonKeyWidth = 0;
public final KeyboardId mId; public final KeyboardId mId;
// Variables for pre-computing nearest keys. // Variables for pre-computing nearest keys.
@ -411,21 +413,33 @@ public class Keyboard {
* @return The most common key width in the keyboard * @return The most common key width in the keyboard
*/ */
public int getMostCommonKeyWidth() { public int getMostCommonKeyWidth() {
final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>(); if (mMostCommonKeyWidth == 0) {
int maxCount = 0; final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>();
int mostCommonWidth = 0; int maxCount = 0;
for (final Key key : mKeys) { int mostCommonWidth = 0;
final Integer width = key.mWidth + key.mGap; for (final Key key : mKeys) {
Integer count = histogram.get(width); final Integer width = key.mWidth + key.mGap;
if (count == null) Integer count = histogram.get(width);
count = 0; if (count == null)
histogram.put(width, ++count); count = 0;
if (count > maxCount) { histogram.put(width, ++count);
maxCount = count; if (count > maxCount) {
mostCommonWidth = width; maxCount = count;
mostCommonWidth = width;
}
} }
mMostCommonKeyWidth = mostCommonWidth;
} }
return mostCommonWidth; return mMostCommonKeyWidth;
}
/**
* Return true if spacebar needs showing preview even when "popup on keypress" is off.
* @param keyIndex index of the pressing key
* @return true if spacebar needs showing preview
*/
public boolean needSpacebarPreview(int keyIndex) {
return false;
} }
private void loadKeyboard(Context context, int xmlLayoutResId) { private void loadKeyboard(Context context, int xmlLayoutResId) {

View file

@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard;
import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -224,7 +223,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
public void popupPreview(long delay, int keyIndex, PointerTracker tracker) { public void popupPreview(long delay, int keyIndex, PointerTracker tracker) {
removeMessages(MSG_POPUP_PREVIEW); removeMessages(MSG_POPUP_PREVIEW);
if (mPreviewText.getVisibility() == VISIBLE) { if (mPreviewText.getVisibility() == VISIBLE || delay == 0) {
// Show right away, if it's already visible and finger is moving around // Show right away, if it's already visible and finger is moving around
showKey(keyIndex, tracker); showKey(keyIndex, tracker);
} else { } else {
@ -889,15 +888,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
public void showPreview(int keyIndex, PointerTracker tracker) { public void showPreview(int keyIndex, PointerTracker tracker) {
int oldKeyIndex = mOldPreviewKeyIndex; int oldKeyIndex = mOldPreviewKeyIndex;
mOldPreviewKeyIndex = keyIndex; mOldPreviewKeyIndex = keyIndex;
// We should re-draw popup preview when 1) we need to hide the preview, 2) we will show if ((mShowPreview && oldKeyIndex != keyIndex) || mKeyboard.needSpacebarPreview(keyIndex)) {
// the space key preview and 3) pointer moves off the space key to other letter key, we
// should hide the preview of the previous key.
final boolean hidePreviewOrShowSpaceKeyPreview = (tracker == null)
|| (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher()
&& SubtypeSwitcher.getInstance().needsToDisplayLanguage()
&& (tracker.isSpaceKey(keyIndex) || tracker.isSpaceKey(oldKeyIndex)));
// If key changed and preview is on or the key is space (language switch is enabled)
if (oldKeyIndex != keyIndex && (mShowPreview || (hidePreviewOrShowSpaceKeyPreview))) {
if (keyIndex == KeyDetector.NOT_A_KEY) { if (keyIndex == KeyDetector.NOT_A_KEY) {
mHandler.cancelPopupPreview(); mHandler.cancelPopupPreview();
mHandler.dismissPreview(mDelayAfterPreview); mHandler.dismissPreview(mDelayAfterPreview);

View file

@ -26,6 +26,9 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Paint.Align; import android.graphics.Paint.Align;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
@ -33,15 +36,18 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import java.lang.ref.SoftReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
// TODO: We should remove this class // TODO: We should remove this class
public class LatinKeyboard extends Keyboard { public class LatinKeyboard extends Keyboard {
public static final int OPACITY_FULLY_OPAQUE = 255;
private static final int SPACE_LED_LENGTH_PERCENT = 80; private static final int SPACE_LED_LENGTH_PERCENT = 80;
private final Context mContext; private final Context mContext;
private final SubtypeSwitcher mSubtypeSwitcher = SubtypeSwitcher.getInstance();
/* Space key and its icons, drawables and colors. */ /* Space key and its icons, drawables and colors. */
private final Key mSpaceKey; private final Key mSpaceKey;
@ -59,14 +65,18 @@ public class LatinKeyboard extends Keyboard {
private int mSpaceDragLastDiff; private int mSpaceDragLastDiff;
private boolean mCurrentlyInSpace; private boolean mCurrentlyInSpace;
private SlidingLocaleDrawable mSlidingLocaleIcon; private SlidingLocaleDrawable mSlidingLocaleIcon;
private final HashMap<Integer, SoftReference<BitmapDrawable>> mSpaceDrawableCache =
new HashMap<Integer, SoftReference<BitmapDrawable>>();
/* Shortcut key and its icons if available */ /* Shortcut key and its icons if available */
private final Key mShortcutKey; private final Key mShortcutKey;
private final Drawable mEnabledShortcutIcon; private final Drawable mEnabledShortcutIcon;
private final Drawable mDisabledShortcutIcon; private final Drawable mDisabledShortcutIcon;
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f; // Minimum width of spacebar dragging to trigger the language switch (represented by the number
// Minimum width of space key preview (proportional to keyboard width) // of the most common key width of this keyboard).
private static final int SPACEBAR_DRAG_WIDTH = 3;
// Minimum width of space key preview (proportional to keyboard width).
private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f; private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f;
// Height in space key the language name will be drawn. (proportional to space key height) // Height in space key the language name will be drawn. (proportional to space key height)
public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f; public static final float SPACEBAR_LANGUAGE_BASELINE = 0.6f;
@ -137,6 +147,12 @@ public class LatinKeyboard extends Keyboard {
return newColor; return newColor;
} }
private static ColorFilter getSpacebarDrawableFilter(float fadeFactor) {
final ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setScale(1, 1, 1, fadeFactor);
return new ColorMatrixColorFilter(colorMatrix);
}
public void updateShortcutKey(boolean available, LatinKeyboardView view) { public void updateShortcutKey(boolean available, LatinKeyboardView view) {
if (mShortcutKey == null) if (mShortcutKey == null)
return; return;
@ -157,19 +173,14 @@ public class LatinKeyboard extends Keyboard {
private void updateSpacebarForLocale(boolean isAutoCorrection) { private void updateSpacebarForLocale(boolean isAutoCorrection) {
if (mSpaceKey == null) if (mSpaceKey == null)
return; return;
final Resources res = mContext.getResources();
// If application locales are explicitly selected. // If application locales are explicitly selected.
if (SubtypeSwitcher.getInstance().needsToDisplayLanguage()) { if (mSubtypeSwitcher.needsToDisplayLanguage()) {
mSpaceKey.setIcon(new BitmapDrawable(res, mSpaceKey.setIcon(getSpaceDrawable(
drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection))); mSubtypeSwitcher.getInputLocale(), isAutoCorrection));
} else if (isAutoCorrection) {
mSpaceKey.setIcon(getSpaceDrawable(null, true));
} else { } else {
// sym_keyboard_space_led can be shared with Black and White symbol themes. mSpaceKey.setIcon(mSpaceIcon);
if (isAutoCorrection) {
mSpaceKey.setIcon(new BitmapDrawable(res,
drawSpacebar(OPACITY_FULLY_OPAQUE, isAutoCorrection)));
} else {
mSpaceKey.setIcon(mSpaceIcon);
}
} }
} }
@ -223,19 +234,31 @@ public class LatinKeyboard extends Keyboard {
return language; return language;
} }
private Bitmap drawSpacebar(int opacity, boolean isAutoCorrection) { private BitmapDrawable getSpaceDrawable(Locale locale, boolean isAutoCorrection) {
final Integer hashCode = Arrays.hashCode(
new Object[] { locale, isAutoCorrection, mSpacebarTextFadeFactor });
final SoftReference<BitmapDrawable> ref = mSpaceDrawableCache.get(hashCode);
BitmapDrawable drawable = (ref == null) ? null : ref.get();
if (drawable == null) {
drawable = new BitmapDrawable(mContext.getResources(), drawSpacebar(
locale, isAutoCorrection, mSpacebarTextFadeFactor));
mSpaceDrawableCache.put(hashCode, new SoftReference<BitmapDrawable>(drawable));
}
return drawable;
}
private Bitmap drawSpacebar(Locale inputLocale, boolean isAutoCorrection,
float textFadeFactor) {
final int width = mSpaceKey.mWidth; final int width = mSpaceKey.mWidth;
final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight; final int height = mSpaceIcon != null ? mSpaceIcon.getIntrinsicHeight() : mSpaceKey.mHeight;
final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(buffer); final Canvas canvas = new Canvas(buffer);
final Resources res = mContext.getResources(); final Resources res = mContext.getResources();
canvas.drawColor(res.getColor(android.R.color.transparent), PorterDuff.Mode.CLEAR); canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
SubtypeSwitcher subtypeSwitcher = SubtypeSwitcher.getInstance();
// If application locales are explicitly selected. // If application locales are explicitly selected.
if (subtypeSwitcher.needsToDisplayLanguage()) { if (inputLocale != null) {
final Paint paint = new Paint(); final Paint paint = new Paint();
paint.setAlpha(opacity);
paint.setAntiAlias(true); paint.setAntiAlias(true);
paint.setTextAlign(Align.CENTER); paint.setTextAlign(Align.CENTER);
@ -253,7 +276,7 @@ public class LatinKeyboard extends Keyboard {
} }
final boolean allowVariableTextSize = true; final boolean allowVariableTextSize = true;
final String language = layoutSpacebar(paint, subtypeSwitcher.getInputLocale(), final String language = layoutSpacebar(paint, inputLocale,
mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height, mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
getTextSizeFromTheme(mContext.getTheme(), textStyle, defaultTextSize), getTextSizeFromTheme(mContext.getTheme(), textStyle, defaultTextSize),
allowVariableTextSize); allowVariableTextSize);
@ -265,14 +288,16 @@ public class LatinKeyboard extends Keyboard {
final float textHeight = -paint.ascent() + descent; final float textHeight = -paint.ascent() + descent;
final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE final float baseline = (mSpaceIcon != null) ? height * SPACEBAR_LANGUAGE_BASELINE
: height / 2 + textHeight / 2; : height / 2 + textHeight / 2;
paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, mSpacebarTextFadeFactor)); paint.setColor(getSpacebarTextColor(mSpacebarTextShadowColor, textFadeFactor));
canvas.drawText(language, width / 2, baseline - descent - 1, paint); canvas.drawText(language, width / 2, baseline - descent - 1, paint);
paint.setColor(getSpacebarTextColor(mSpacebarTextColor, mSpacebarTextFadeFactor)); paint.setColor(getSpacebarTextColor(mSpacebarTextColor, textFadeFactor));
canvas.drawText(language, width / 2, baseline - descent, paint); canvas.drawText(language, width / 2, baseline - descent, paint);
// Put arrows that are already layed out on either side of the text // Put arrows that are already layed out on either side of the text
if (subtypeSwitcher.useSpacebarLanguageSwitcher() if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()
&& subtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) { && mSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
mButtonArrowLeftIcon.setColorFilter(getSpacebarDrawableFilter(textFadeFactor));
mButtonArrowRightIcon.setColorFilter(getSpacebarDrawableFilter(textFadeFactor));
mButtonArrowLeftIcon.draw(canvas); mButtonArrowLeftIcon.draw(canvas);
mButtonArrowRightIcon.draw(canvas); mButtonArrowRightIcon.draw(canvas);
} }
@ -316,9 +341,25 @@ public class LatinKeyboard extends Keyboard {
mSpaceKey.getPreviewIcon().invalidateSelf(); mSpaceKey.getPreviewIcon().invalidateSelf();
} }
// This method is called when "popup on keypress" is off.
@Override
public boolean needSpacebarPreview(int keyIndex) {
if (!mSubtypeSwitcher.useSpacebarLanguageSwitcher())
return false;
// Dismiss key preview.
if (keyIndex == KeyDetector.NOT_A_KEY)
return true;
// Key is not a spacebar.
if (keyIndex != mSpaceKeyIndexArray[0])
return false;
// The language switcher will be displayed only when the dragging distance is greater
// than average key width of this keyboard.
return Math.abs(mSpaceDragLastDiff) > getMostCommonKeyWidth();
}
public int getLanguageChangeDirection() { public int getLanguageChangeDirection() {
if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1 if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1
|| Math.abs(mSpaceDragLastDiff) < mSpaceKey.mWidth * SPACEBAR_DRAG_THRESHOLD) { || Math.abs(mSpaceDragLastDiff) < getMostCommonKeyWidth() * SPACEBAR_DRAG_WIDTH) {
return 0; // No change return 0; // No change
} }
return mSpaceDragLastDiff > 0 ? 1 : -1; return mSpaceDragLastDiff > 0 ? 1 : -1;

View file

@ -23,6 +23,7 @@ import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
@ -63,9 +64,8 @@ public class SlidingLocaleDrawable extends Drawable {
mHeight = height; mHeight = height;
final TextPaint textPaint = new TextPaint(); final TextPaint textPaint = new TextPaint();
textPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18)); textPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18));
textPaint.setColor(android.R.color.transparent); textPaint.setColor(Color.TRANSPARENT);
textPaint.setTextAlign(Align.CENTER); textPaint.setTextAlign(Align.CENTER);
textPaint.setAlpha(LatinKeyboard.OPACITY_FULLY_OPAQUE);
textPaint.setAntiAlias(true); textPaint.setAntiAlias(true);
mTextPaint = textPaint; mTextPaint = textPaint;
mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2; mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2;