Choose smaller or shorter language name for space bar

To fit a language name to the space bar or the language switcher, this
change chooses smaller text size or shorter language name
appropriately.

This change also tunes the vertical position of a language name in the
space bar by parameter SPACEBAR_LANGUAGE_BASELINE.

Bug: 3004640
Bug: 3001021

Change-Id: Idb3adcb6fac1a23836510912d35312fa11b4f259
main
Tadashi G. Takaoka 2010-09-17 20:25:13 +09:00
parent 3a2896c804
commit 8243c7a5e5
2 changed files with 125 additions and 85 deletions

View File

@ -99,6 +99,13 @@ public class LatinKeyboard extends Keyboard {
private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f; private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f; private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f; private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f;
// Minimum width of space key preview (proportional to keyboard width)
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)
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 static int sSpacebarVerticalCorrection; private static int sSpacebarVerticalCorrection;
@ -405,43 +412,94 @@ public class LatinKeyboard extends Keyboard {
} }
} }
// 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 space bar.
private static String layoutSpaceBar(Paint paint, Locale locale, Drawable lArrow,
Drawable rArrow, int width, int height, float origTextSize,
boolean allowVariableTextSize) {
final float arrowWidth = lArrow.getIntrinsicWidth();
final float arrowHeight = lArrow.getIntrinsicHeight();
final float maxTextWidth = width - (arrowWidth + arrowWidth);
final Rect bounds = new Rect();
// Estimate appropriate language name text size to fit in maxTextWidth.
String language = LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale));
int textWidth = getTextWidth(paint, language, origTextSize, bounds);
// Assuming text width and text size are proportional to each other.
float textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
final boolean useShortName;
if (allowVariableTextSize) {
textWidth = getTextWidth(paint, language, textSize, bounds);
// If text size goes too small or text does not fit, use short name
useShortName = textSize / origTextSize < MINIMUM_SCALE_OF_LANGUAGE_NAME
|| textWidth > maxTextWidth;
} else {
useShortName = textWidth > maxTextWidth;
textSize = origTextSize;
}
if (useShortName) {
language = LanguageSwitcher.toTitleCase(locale.getLanguage());
textWidth = getTextWidth(paint, language, origTextSize, bounds);
textSize = origTextSize * Math.min(maxTextWidth / textWidth, 1.0f);
}
paint.setTextSize(textSize);
// Place left and right arrow just before and after language text.
final float baseline = height * SPACEBAR_LANGUAGE_BASELINE;
final int top = (int)(baseline - arrowHeight);
final float remains = (width - textWidth) / 2;
lArrow.setBounds((int)(remains - arrowWidth), top, (int)remains, (int)baseline);
rArrow.setBounds((int)(remains + textWidth), top, (int)(remains + textWidth + arrowWidth),
(int)baseline);
return language;
}
private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion, boolean isBlack) { private Bitmap drawSpaceBar(int opacity, boolean isAutoCompletion, boolean isBlack) {
int width = mSpaceKey.width; final int width = mSpaceKey.width;
int height = mSpaceIcon.getIntrinsicHeight(); final int height = mSpaceIcon.getIntrinsicHeight();
Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); final Bitmap buffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(buffer); final Canvas canvas = new Canvas(buffer);
canvas.drawColor(mRes.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR); canvas.drawColor(mRes.getColor(R.color.latinkeyboard_transparent), PorterDuff.Mode.CLEAR);
// If application locales are explicitly selected. // If application locales are explicitly selected.
if (mLocale != null) { if (mLocale != null) {
Paint paint = new Paint(); final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setAlpha(opacity); paint.setAlpha(opacity);
// Get the text size from the theme paint.setAntiAlias(true);
paint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Small, 14));
paint.setTextAlign(Align.CENTER); paint.setTextAlign(Align.CENTER);
final String language = getInputLanguage(mSpaceKey.width, paint);
final int ascent = (int) -paint.ascent();
int shadowColor = isBlack ? final boolean allowVariableTextSize = true;
mRes.getColor(R.color.latinkeyboard_bar_language_shadow_black) final String language = layoutSpaceBar(paint, mLanguageSwitcher.getInputLocale(),
: mRes.getColor(R.color.latinkeyboard_bar_language_shadow_white); mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
getTextSizeFromTheme(android.R.style.TextAppearance_Small, 14),
allowVariableTextSize);
// Draw language text with shadow
final int shadowColor = mRes.getColor(isBlack
? R.color.latinkeyboard_bar_language_shadow_black
: R.color.latinkeyboard_bar_language_shadow_white);
final float baseline = height * SPACEBAR_LANGUAGE_BASELINE;
final float descent = paint.descent();
paint.setColor(shadowColor); paint.setColor(shadowColor);
canvas.drawText(language, width / 2, ascent - 1, paint); canvas.drawText(language, width / 2, baseline - descent - 1, paint);
paint.setColor(mRes.getColor(R.color.latinkeyboard_bar_language_text)); paint.setColor(mRes.getColor(R.color.latinkeyboard_bar_language_text));
canvas.drawText(language, width / 2, ascent, paint); canvas.drawText(language, width / 2, baseline - descent, paint);
// Put arrows on either side of the text
// Put arrows that are already layed out on either side of the text
if (mLanguageSwitcher.getLocaleCount() > 1) { if (mLanguageSwitcher.getLocaleCount() > 1) {
Rect bounds = new Rect(); mButtonArrowLeftIcon.draw(canvas);
paint.getTextBounds(language, 0, language.length(), bounds); mButtonArrowRightIcon.draw(canvas);
drawButtonArrow(mButtonArrowLeftIcon, canvas,
(mSpaceKey.width - bounds.right) / 2
- mButtonArrowLeftIcon.getIntrinsicWidth(),
(int) paint.getTextSize());
drawButtonArrow(mButtonArrowRightIcon, canvas,
(mSpaceKey.width + bounds.right) / 2, (int) paint.getTextSize());
} }
} }
// Draw the spacebar icon at the bottom // Draw the spacebar icon at the bottom
if (isAutoCompletion) { if (isAutoCompletion) {
final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100; final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100;
@ -461,38 +519,13 @@ public class LatinKeyboard extends Keyboard {
return buffer; return buffer;
} }
private void drawButtonArrow(Drawable arrow, Canvas canvas, int x, int bottomY) {
arrow.setBounds(x, bottomY - arrow.getIntrinsicHeight(), x + arrow.getIntrinsicWidth(),
bottomY);
arrow.draw(canvas);
}
private String getInputLanguage(int widthAvail, Paint paint) {
return chooseDisplayName(mLanguageSwitcher.getInputLocale(), widthAvail, paint);
}
private String getNextInputLanguage(int widthAvail, Paint paint) {
return chooseDisplayName(mLanguageSwitcher.getNextInputLocale(), widthAvail, paint);
}
private String getPrevInputLanguage(int widthAvail, Paint paint) {
return chooseDisplayName(mLanguageSwitcher.getPrevInputLocale(), widthAvail, paint);
}
private String chooseDisplayName(Locale locale, int widthAvail, Paint paint) {
if (widthAvail < (int) (.35 * getMinWidth())) {
return LanguageSwitcher.toTitleCase(locale.getLanguage().substring(0, 2));
} else {
return LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale));
}
}
private void updateLocaleDrag(int diff) { private void updateLocaleDrag(int diff) {
if (mSlidingLocaleIcon == null) { if (mSlidingLocaleIcon == null) {
mSlidingLocaleIcon = new SlidingLocaleDrawable(mSpacePreviewIcon, mSpaceKey.width, final int width = Math.max(mSpaceKey.width,
mSpacePreviewIcon.getIntrinsicHeight()); (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO));
mSlidingLocaleIcon.setBounds(0, 0, mSpaceKey.width, final int height = mSpacePreviewIcon.getIntrinsicHeight();
mSpacePreviewIcon.getIntrinsicHeight()); mSlidingLocaleIcon = new SlidingLocaleDrawable(mSpacePreviewIcon, width, height);
mSlidingLocaleIcon.setBounds(0, 0, width, height);
mSpaceKey.iconPreview = mSlidingLocaleIcon; mSpaceKey.iconPreview = mSlidingLocaleIcon;
} }
mSlidingLocaleIcon.setDiff(diff); mSlidingLocaleIcon.setDiff(diff);
@ -777,17 +810,16 @@ public class LatinKeyboard extends Keyboard {
*/ */
class SlidingLocaleDrawable extends Drawable { class SlidingLocaleDrawable extends Drawable {
private int mWidth; private final int mWidth;
private int mHeight; private final int mHeight;
private Drawable mBackground; private final Drawable mBackground;
private final TextPaint mTextPaint;
private final int mMiddleX;
private final Drawable mLeftDrawable;
private final Drawable mRightDrawable;
private final int mThreshold;
private int mDiff; private int mDiff;
private TextPaint mTextPaint;
private int mMiddleX;
private int mAscent;
private Drawable mLeftDrawable;
private Drawable mRightDrawable;
private boolean mHitThreshold; private boolean mHitThreshold;
private int mThreshold;
private String mCurrentLanguage; private String mCurrentLanguage;
private String mNextLanguage; private String mNextLanguage;
private String mPrevLanguage; private String mPrevLanguage;
@ -799,26 +831,20 @@ public class LatinKeyboard extends Keyboard {
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
mTextPaint = new TextPaint(); mTextPaint = new TextPaint();
int textSize = getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18); mTextPaint.setTextSize(getTextSizeFromTheme(android.R.style.TextAppearance_Medium, 18));
mTextPaint.setTextSize(textSize);
mTextPaint.setColor(R.color.latinkeyboard_transparent); mTextPaint.setColor(R.color.latinkeyboard_transparent);
mTextPaint.setTextAlign(Align.CENTER); mTextPaint.setTextAlign(Align.CENTER);
mTextPaint.setAlpha(OPACITY_FULLY_OPAQUE); mTextPaint.setAlpha(OPACITY_FULLY_OPAQUE);
mTextPaint.setAntiAlias(true); mTextPaint.setAntiAlias(true);
mAscent = (int) mTextPaint.ascent();
mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2; mMiddleX = (mWidth - mBackground.getIntrinsicWidth()) / 2;
mLeftDrawable = mLeftDrawable =
mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_left); mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_left);
mRightDrawable = mRightDrawable =
mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_right); mRes.getDrawable(R.drawable.sym_keyboard_feedback_language_arrows_right);
mLeftDrawable.setBounds(0, 0,
mLeftDrawable.getIntrinsicWidth(), mLeftDrawable.getIntrinsicHeight());
mRightDrawable.setBounds(mWidth - mRightDrawable.getIntrinsicWidth(), 0,
mWidth, mRightDrawable.getIntrinsicHeight());
mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop(); mThreshold = ViewConfiguration.get(mContext).getScaledTouchSlop();
} }
void setDiff(int diff) { private void setDiff(int diff) {
if (diff == Integer.MAX_VALUE) { if (diff == Integer.MAX_VALUE) {
mHitThreshold = false; mHitThreshold = false;
mCurrentLanguage = null; mCurrentLanguage = null;
@ -831,25 +857,39 @@ public class LatinKeyboard extends Keyboard {
invalidateSelf(); invalidateSelf();
} }
private String getLanguageName(Locale locale) {
return LanguageSwitcher.toTitleCase(locale.getDisplayLanguage(locale));
}
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
canvas.save(); canvas.save();
if (mHitThreshold) { if (mHitThreshold) {
mTextPaint.setColor(mRes.getColor(R.color.latinkeyboard_feedback_language_text)); Paint paint = mTextPaint;
canvas.clipRect(0, 0, mWidth, mHeight); final int width = mWidth;
final int height = mHeight;
final int diff = mDiff;
final Drawable lArrow = mLeftDrawable;
final Drawable rArrow = mRightDrawable;
canvas.clipRect(0, 0, width, height);
if (mCurrentLanguage == null) { if (mCurrentLanguage == null) {
mCurrentLanguage = getInputLanguage(mWidth, mTextPaint); final LanguageSwitcher languageSwitcher = mLanguageSwitcher;
mNextLanguage = getNextInputLanguage(mWidth, mTextPaint); mCurrentLanguage = getLanguageName(languageSwitcher.getInputLocale());
mPrevLanguage = getPrevInputLanguage(mWidth, mTextPaint); mNextLanguage = getLanguageName(languageSwitcher.getNextInputLocale());
mPrevLanguage = getLanguageName(languageSwitcher.getPrevInputLocale());
} }
canvas.drawText(mCurrentLanguage, // Draw language text with shadow
mWidth / 2 + mDiff, -mAscent + 4, mTextPaint); final float baseline = mHeight * SPACEBAR_LANGUAGE_BASELINE - paint.descent();
canvas.drawText(mNextLanguage, paint.setColor(mRes.getColor(R.color.latinkeyboard_feedback_language_text));
mDiff - mWidth / 2, -mAscent + 4, mTextPaint); canvas.drawText(mCurrentLanguage, width / 2 + diff, baseline, paint);
canvas.drawText(mPrevLanguage, canvas.drawText(mNextLanguage, diff - width / 2, baseline, paint);
mDiff + mWidth + mWidth / 2, -mAscent + 4, mTextPaint); canvas.drawText(mPrevLanguage, diff + width + width / 2, baseline, paint);
mLeftDrawable.draw(canvas);
mRightDrawable.draw(canvas); lArrow.setBounds(0, 0, lArrow.getIntrinsicWidth(), lArrow.getIntrinsicHeight());
rArrow.setBounds(width - rArrow.getIntrinsicWidth(), 0, width,
rArrow.getIntrinsicHeight());
lArrow.draw(canvas);
rArrow.draw(canvas);
} }
if (mBackground != null) { if (mBackground != null) {
canvas.translate(mMiddleX, 0); canvas.translate(mMiddleX, 0);

View File

@ -932,7 +932,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
lp.height = popupHeight; lp.height = popupHeight;
} }
int popupPreviewX = key.x - mPreviewText.getPaddingLeft() + getPaddingLeft(); int popupPreviewX = key.x - (popupWidth - key.width) / 2;
int popupPreviewY = key.y - popupHeight + mPreviewOffset; int popupPreviewY = key.y - popupHeight + mPreviewOffset;
mHandler.cancelDismissPreview(); mHandler.cancelDismissPreview();