diff options
Diffstat (limited to 'java/src')
6 files changed, 136 insertions, 52 deletions
diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboard.java b/java/src/com/android/inputmethod/latin/BaseKeyboard.java index 485cc3153..00ed453c4 100644 --- a/java/src/com/android/inputmethod/latin/BaseKeyboard.java +++ b/java/src/com/android/inputmethod/latin/BaseKeyboard.java @@ -28,11 +28,14 @@ import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.text.TextUtils; +import android.util.Log; import android.util.Xml; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard @@ -86,6 +89,9 @@ public class BaseKeyboard { /** List of shift keys in this keyboard */ private final List<Key> mShiftKeys = new ArrayList<Key>(); + /** List of shift keys and its shifted state icon */ + private final HashMap<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>(); + /** Total height of the keyboard, including the padding and keys */ private int mTotalHeight; @@ -340,6 +346,10 @@ public class BaseKeyboard { manualTemporaryUpperCaseCode = style.getInt(a, R.styleable.BaseKeyboard_Key_manualTemporaryUpperCaseCode, 0); text = style.getText(a, R.styleable.BaseKeyboard_Key_keyOutputText); + final Drawable shiftedIcon = style.getDrawable(a, + R.styleable.BaseKeyboard_Key_shiftedIcon); + if (shiftedIcon != null) + keyboard.getShiftedIcons().put(this, shiftedIcon); if (codes == null && !TextUtils.isEmpty(label)) { codes = new int[] { label.charAt(0) }; @@ -622,6 +632,10 @@ public class BaseKeyboard { return mShiftKeys; } + public Map<Key, Drawable> getShiftedIcons() { + return mShiftedIcons; + } + private void computeNearestNeighbors() { // Round-up so we don't have any pixels outside the grid mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH; @@ -686,8 +700,10 @@ public class BaseKeyboard { mTotalWidth = parser.getMaxRowWidth(); mTotalHeight = parser.getTotalHeight(); } catch (XmlPullParserException e) { + Log.w(TAG, "keyboard XML parse error: " + e); throw new IllegalArgumentException(e); } catch (IOException e) { + Log.w(TAG, "keyboard XML parse error: " + e); throw new RuntimeException(e); } } diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java b/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java index 621e875bf..38b2a1b57 100644 --- a/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java +++ b/java/src/com/android/inputmethod/latin/BaseKeyboardParser.java @@ -174,6 +174,7 @@ public class BaseKeyboardParser { keyboard.setVerticalGap(getDimensionOrFraction(a, R.styleable.BaseKeyboard_verticalGap, height, 0)); a.recycle(); + if (DEBUG_TAG) Log.d(TAG, "id=" + keyboard.mId); } private void parseKeyboardContent(XmlResourceParser parser, List<Key> keys) @@ -310,6 +311,7 @@ public class BaseKeyboardParser { checkEndTag(TAG_INCLUDE, parser); if (keyboardLayout == 0) throw new ParseException("No keyboardLayout attribute in <include/>", parser); + if (DEBUG_TAG) Log.d(TAG, String.format(" keyboardLayout=0x%08x", keyboardLayout)); parseMerge(mResources.getLayout(keyboardLayout), row, keys); } } @@ -560,10 +562,10 @@ public class BaseKeyboardParser { } private static String debugInteger(TypedArray a, int index, String name) { - return a.hasValue(index) ? name + "=" + a.getInt(index, 0) : ""; + return a.hasValue(index) ? " " + name + "=" + a.getInt(index, 0) : ""; } private static String debugBoolean(TypedArray a, int index, String name) { - return a.hasValue(index) ? name + "=" + a.getBoolean(index, false) : ""; + return a.hasValue(index) ? " " + name + "=" + a.getBoolean(index, false) : ""; } } diff --git a/java/src/com/android/inputmethod/latin/BaseKeyboardView.java b/java/src/com/android/inputmethod/latin/BaseKeyboardView.java index 129ff81a1..954f264bd 100644 --- a/java/src/com/android/inputmethod/latin/BaseKeyboardView.java +++ b/java/src/com/android/inputmethod/latin/BaseKeyboardView.java @@ -71,6 +71,7 @@ import java.util.WeakHashMap; public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private static final String TAG = "BaseKeyboardView"; private static final boolean DEBUG = false; + private static final boolean DEBUG_SHOW_ALIGN = false; private static final boolean DEBUG_KEYBOARD_GRID = false; public static final int COLOR_SCHEME_WHITE = 0; @@ -252,17 +253,15 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { private final Rect mClipRegion = new Rect(0, 0, 0, 0); // This map caches key label text height in pixel as value and key label text size as map key. private final HashMap<Integer, Integer> mTextHeightCache = new HashMap<Integer, Integer>(); - // This map caches key label text width in pixel as value and key label text size as map key. - private final HashMap<Integer, Integer> mTextWidthCache = new HashMap<Integer, Integer>(); // Distance from horizontal center of the key, proportional to key label text height and width. private final float KEY_LABEL_VERTICAL_ADJUSTMENT_FACTOR_CENTER = 0.55f; private final float KEY_LABEL_VERTICAL_PADDING_FACTOR = 1.60f; - private final float KEY_LABEL_HORIZONTAL_PADDING_FACTOR = 0.80f; private final String KEY_LABEL_REFERENCE_CHAR = "H"; private final int KEY_LABEL_OPTION_ALIGN_LEFT = 1; private final int KEY_LABEL_OPTION_ALIGN_RIGHT = 2; private final int KEY_LABEL_OPTION_ALIGN_BOTTOM = 8; private final int KEY_LABEL_OPTION_FONT_NORMAL = 16; + private final int mKeyLabelHorizontalPadding; private final UIHandler mHandler = new UIHandler(); @@ -514,6 +513,8 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview); mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview); + mKeyLabelHorizontalPadding = (int)res.getDimension( + R.dimen.key_label_horizontal_alignment_padding); mMiniKeyboardParent = this; mMiniKeyboardPopup = new PopupWindow(context); @@ -818,44 +819,22 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop); keyBackground.draw(canvas); + final int rowHeight = padding.top + key.height; boolean drawHintIcon = true; // Draw key label if (label != null) { // For characters, use large font. For labels like "Done", use small font. - final int labelSize; - if (label.length() > 1 && key.codes.length < 2) { - labelSize = mLabelTextSize; - if ((key.labelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) { - paint.setTypeface(Typeface.DEFAULT); - } else { - paint.setTypeface(Typeface.DEFAULT_BOLD); - } - } else { - labelSize = mKeyTextSize; - paint.setTypeface(mKeyTextStyle); - } - paint.setTextSize(labelSize); - - Integer labelHeightValue = mTextHeightCache.get(labelSize); - final int labelCharHeight; - final int labelCharWidth; - if (labelHeightValue != null) { - labelCharHeight = labelHeightValue; - labelCharWidth = mTextWidthCache.get(labelSize); - } else { - Rect textBounds = new Rect(); - paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, textBounds); - labelCharHeight = textBounds.height(); - labelCharWidth = textBounds.width(); - mTextHeightCache.put(labelSize, labelCharHeight); - mTextWidthCache.put(labelSize, labelCharWidth); - } + final int labelSize = getLabelSizeAndSetPaint(label, key, paint); + final int labelCharHeight = getLabelCharHeight(labelSize, paint); // Vertical label text alignment. final float baseline; if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_BOTTOM) != 0) { baseline = key.height - + labelCharHeight * KEY_LABEL_VERTICAL_PADDING_FACTOR; + if (DEBUG_SHOW_ALIGN) + drawHorizontalLine(canvas, (int)baseline, key.width, 0xc0008000, + new Paint()); } else { // Align center final float centerY = (key.height + padding.top - padding.bottom) / 2; baseline = centerY @@ -864,16 +843,20 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { // Horizontal label text alignment final int positionX; if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { - positionX = (int)( - labelCharWidth * KEY_LABEL_HORIZONTAL_PADDING_FACTOR + padding.left); + positionX = mKeyLabelHorizontalPadding + padding.left; paint.setTextAlign(Align.LEFT); + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, positionX, rowHeight, 0xc0800080, new Paint()); } else if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { - positionX = (int)(key.width - - labelCharWidth * KEY_LABEL_HORIZONTAL_PADDING_FACTOR - padding.right); + positionX = key.width - mKeyLabelHorizontalPadding - padding.right; paint.setTextAlign(Align.RIGHT); + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, positionX, rowHeight, 0xc0808000, new Paint()); } else { positionX = (key.width + padding.left - padding.right) / 2; paint.setTextAlign(Align.CENTER); + if (DEBUG_SHOW_ALIGN && label.length() > 1) + drawVerticalLine(canvas, positionX, rowHeight, 0xc0008080, new Paint()); } // Set a drop shadow for the text paint.setShadowLayer(mShadowRadius, 0, 0, mShadowColor); @@ -883,21 +866,44 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { } // Draw key icon if (key.label == null && key.icon != null) { - int drawableWidth = key.icon.getIntrinsicWidth(); - int drawableHeight = key.icon.getIntrinsicHeight(); - int drawableX = (key.width + padding.left - padding.right - drawableWidth) / 2; - int drawableY = (key.height + padding.top - padding.bottom - drawableHeight) / 2; + final int drawableWidth = key.icon.getIntrinsicWidth(); + final int drawableHeight = key.icon.getIntrinsicHeight(); + final int drawableX; + final int drawableY = ( + key.height + padding.top - padding.bottom - drawableHeight) / 2; + if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_LEFT) != 0) { + drawableX = padding.left + mKeyLabelHorizontalPadding; + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, drawableX, rowHeight, 0xc0800080, new Paint()); + } else if ((key.labelOption & KEY_LABEL_OPTION_ALIGN_RIGHT) != 0) { + drawableX = key.width - padding.right - mKeyLabelHorizontalPadding + - drawableWidth; + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, drawableX + drawableWidth, rowHeight, + 0xc0808000, new Paint()); + } else { // Align center + drawableX = (key.width + padding.left - padding.right - drawableWidth) / 2; + if (DEBUG_SHOW_ALIGN) + drawVerticalLine(canvas, drawableX + drawableWidth / 2, rowHeight, + 0xc0008080, new Paint()); + } drawIcon(canvas, key.icon, drawableX, drawableY, drawableWidth, drawableHeight); + if (DEBUG_SHOW_ALIGN) + drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, + 0x80c00000, new Paint()); } if (key.hintIcon != null && drawHintIcon) { - int drawableWidth = key.width; - int drawableHeight = key.height; - int drawableX = 0; - int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL; + final int drawableWidth = key.width; + final int drawableHeight = key.height; + final int drawableX = 0; + final int drawableY = HINT_ICON_VERTICAL_ADJUSTMENT_PIXEL; Drawable icon = (isManualTemporaryUpperCase && key.manualTemporaryUpperCaseHintIcon != null) ? key.manualTemporaryUpperCaseHintIcon : key.hintIcon; drawIcon(canvas, icon, drawableX, drawableY, drawableWidth, drawableHeight); + if (DEBUG_SHOW_ALIGN) + drawRectangle(canvas, drawableX, drawableY, drawableWidth, drawableHeight, + 0x80c0c000, new Paint()); } canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop); } @@ -945,13 +951,70 @@ public class BaseKeyboardView extends View implements PointerTracker.UIProxy { mDirtyRect.setEmpty(); } - private void drawIcon(Canvas canvas, Drawable icon, int x, int y, int width, int height) { + private int getLabelSizeAndSetPaint(CharSequence label, Key key, Paint paint) { + // For characters, use large font. For labels like "Done", use small font. + final int labelSize; + if (label.length() > 1 && key.codes.length < 2) { + labelSize = mLabelTextSize; + if ((key.labelOption & KEY_LABEL_OPTION_FONT_NORMAL) != 0) { + paint.setTypeface(Typeface.DEFAULT); + } else { + paint.setTypeface(Typeface.DEFAULT_BOLD); + } + } else { + labelSize = mKeyTextSize; + paint.setTypeface(mKeyTextStyle); + } + paint.setTextSize(labelSize); + return labelSize; + } + + private int getLabelCharHeight(int labelSize, Paint paint) { + Integer labelHeightValue = mTextHeightCache.get(labelSize); + final int labelCharHeight; + if (labelHeightValue != null) { + labelCharHeight = labelHeightValue; + } else { + Rect textBounds = new Rect(); + paint.getTextBounds(KEY_LABEL_REFERENCE_CHAR, 0, 1, textBounds); + labelCharHeight = textBounds.height(); + mTextHeightCache.put(labelSize, labelCharHeight); + } + return labelCharHeight; + } + + private static void drawIcon(Canvas canvas, Drawable icon, int x, int y, int width, + int height) { canvas.translate(x, y); icon.setBounds(0, 0, width, height); icon.draw(canvas); canvas.translate(-x, -y); } + private static void drawHorizontalLine(Canvas canvas, int y, int w, int color, Paint paint) { + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(1.0f); + paint.setColor(color); + canvas.drawLine(0, y, w, y, paint); + } + + private static void drawVerticalLine(Canvas canvas, int x, int h, int color, Paint paint) { + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(1.0f); + paint.setColor(color); + canvas.drawLine(x, 0, x, h, paint); + } + + private static void drawRectangle(Canvas canvas, int x, int y, int w, int h, int color, + Paint paint) { + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(1.0f); + paint.setColor(color); + canvas.translate(x, y); + canvas.drawRect(0, 0, w, h, paint); + canvas.translate(-x, -y); + } + public void setForeground(boolean foreground) { mInForeground = foreground; } diff --git a/java/src/com/android/inputmethod/latin/KeyStyles.java b/java/src/com/android/inputmethod/latin/KeyStyles.java index e53e351a3..fceede7c3 100644 --- a/java/src/com/android/inputmethod/latin/KeyStyles.java +++ b/java/src/com/android/inputmethod/latin/KeyStyles.java @@ -104,7 +104,7 @@ public class KeyStyles { try { values[count++] = Integer.parseInt(st.nextToken()); } catch (NumberFormatException nfe) { - Log.e(TAG, "Error parsing integer CSV " + value); + Log.w(TAG, "Error parsing integer CSV " + value); } } return values; @@ -163,6 +163,7 @@ public class KeyStyles { readDrawable(a, R.styleable.BaseKeyboard_Key_keyIcon); readDrawable(a, R.styleable.BaseKeyboard_Key_iconPreview); readDrawable(a, R.styleable.BaseKeyboard_Key_keyHintIcon); + readDrawable(a, R.styleable.BaseKeyboard_Key_shiftedIcon); readResourceId(a, R.styleable.BaseKeyboard_Key_popupKeyboard); readBoolean(a, R.styleable.BaseKeyboard_Key_isModifier); readBoolean(a, R.styleable.BaseKeyboard_Key_isSticky); diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java index 58958b610..b08b97a81 100644 --- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java @@ -691,9 +691,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha ).inflate(THEMES[newLayout], null); tryGC = false; } catch (OutOfMemoryError e) { + Log.w(TAG, "load keyboard failed: " + e); tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait( mLayoutId + "," + newLayout, e); } catch (InflateException e) { + Log.w(TAG, "load keyboard failed: " + e); tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait( mLayoutId + "," + newLayout, e); } diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboard.java b/java/src/com/android/inputmethod/latin/LatinKeyboard.java index c6e911680..cae0b10b3 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/latin/LatinKeyboard.java @@ -37,6 +37,7 @@ import android.view.ViewConfiguration; import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Map; public class LatinKeyboard extends BaseKeyboard { @@ -45,7 +46,6 @@ public class LatinKeyboard extends BaseKeyboard { private static final int OPACITY_FULLY_OPAQUE = 255; private static final int SPACE_LED_LENGTH_PERCENT = 80; - private final Drawable mShiftedIcon; private Drawable mShiftLockPreviewIcon; private final HashMap<Key, Drawable> mNormalShiftIcons = new HashMap<Key, Drawable>(); private Drawable mSpaceIcon; @@ -89,11 +89,9 @@ public class LatinKeyboard extends BaseKeyboard { mContext = context; mRes = res; if (id.mColorScheme == BaseKeyboardView.COLOR_SCHEME_BLACK) { - mShiftedIcon = res.getDrawable(R.drawable.sym_bkeyboard_shift_locked); mSpaceBarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_black); } else { // default color scheme is BaseKeyboardView.COLOR_SCHEME_WHITE - mShiftedIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked); mSpaceBarTextShadowColor = res.getColor( R.color.latinkeyboard_bar_language_shadow_white); } @@ -132,9 +130,10 @@ public class LatinKeyboard extends BaseKeyboard { } public boolean setShiftLocked(boolean newShiftLockState) { + final Map<Key, Drawable> shiftedIcons = getShiftedIcons(); for (final Key key : getShiftKeys()) { key.on = newShiftLockState; - key.icon = newShiftLockState ? mShiftedIcon : mNormalShiftIcons.get(key); + key.icon = newShiftLockState ? shiftedIcons.get(key) : mNormalShiftIcons.get(key); } mShiftState.setShiftLocked(newShiftLockState); return true; @@ -149,11 +148,12 @@ public class LatinKeyboard extends BaseKeyboard { if (getShiftKeys().size() == 0) return super.setShifted(newShiftState); + final Map<Key, Drawable> shiftedIcons = getShiftedIcons(); for (final Key key : getShiftKeys()) { if (!newShiftState && !mShiftState.isShiftLocked()) { key.icon = mNormalShiftIcons.get(key); } else if (newShiftState && !mShiftState.isShiftedOrShiftLocked()) { - key.icon = mShiftedIcon; + key.icon = shiftedIcons.get(key); } } return mShiftState.setShifted(newShiftState); |