1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.inputmethod.keyboard.internal; 18 19 import android.content.Context; 20 import android.graphics.Rect; 21 import android.graphics.drawable.Drawable; 22 import android.text.TextPaint; 23 import android.text.TextUtils; 24 import android.util.AttributeSet; 25 import android.util.TypedValue; 26 import android.view.Gravity; 27 import android.widget.TextView; 28 29 import com.android.inputmethod.keyboard.Key; 30 import com.android.inputmethod.latin.R; 31 32 import java.util.HashSet; 33 34 /** 35 * The pop up key preview view. 36 */ 37 public class KeyPreviewView extends TextView { 38 public static final int POSITION_MIDDLE = 0; 39 public static final int POSITION_LEFT = 1; 40 public static final int POSITION_RIGHT = 2; 41 42 private final Rect mBackgroundPadding = new Rect(); 43 private static final HashSet<String> sNoScaleXTextSet = new HashSet<>(); 44 KeyPreviewView(final Context context, final AttributeSet attrs)45 public KeyPreviewView(final Context context, final AttributeSet attrs) { 46 this(context, attrs, 0); 47 } 48 KeyPreviewView(final Context context, final AttributeSet attrs, final int defStyleAttr)49 public KeyPreviewView(final Context context, final AttributeSet attrs, final int defStyleAttr) { 50 super(context, attrs, defStyleAttr); 51 setGravity(Gravity.CENTER); 52 } 53 setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams)54 public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet, 55 final KeyDrawParams drawParams) { 56 // What we show as preview should match what we show on a key top in onDraw(). 57 final int iconId = key.getIconId(); 58 if (iconId != KeyboardIconsSet.ICON_UNDEFINED) { 59 setCompoundDrawables(null, null, null, key.getPreviewIcon(iconsSet)); 60 setText(null); 61 return; 62 } 63 64 setCompoundDrawables(null, null, null, null); 65 setTextColor(drawParams.mPreviewTextColor); 66 setTextSize(TypedValue.COMPLEX_UNIT_PX, key.selectPreviewTextSize(drawParams)); 67 setTypeface(key.selectPreviewTypeface(drawParams)); 68 // TODO Should take care of temporaryShiftLabel here. 69 setTextAndScaleX(key.getPreviewLabel()); 70 } 71 setTextAndScaleX(final String text)72 private void setTextAndScaleX(final String text) { 73 setTextScaleX(1.0f); 74 setText(text); 75 if (sNoScaleXTextSet.contains(text)) { 76 return; 77 } 78 // TODO: Override {@link #setBackground(Drawable)} that is supported from API 16 and 79 // calculate maximum text width. 80 final Drawable background = getBackground(); 81 if (background == null) { 82 return; 83 } 84 background.getPadding(mBackgroundPadding); 85 final int maxWidth = background.getIntrinsicWidth() - mBackgroundPadding.left 86 - mBackgroundPadding.right; 87 final float width = getTextWidth(text, getPaint()); 88 if (width <= maxWidth) { 89 sNoScaleXTextSet.add(text); 90 return; 91 } 92 setTextScaleX(maxWidth / width); 93 } 94 clearTextCache()95 public static void clearTextCache() { 96 sNoScaleXTextSet.clear(); 97 } 98 getTextWidth(final String text, final TextPaint paint)99 private static float getTextWidth(final String text, final TextPaint paint) { 100 if (TextUtils.isEmpty(text)) { 101 return 0.0f; 102 } 103 final int len = text.length(); 104 final float[] widths = new float[len]; 105 final int count = paint.getTextWidths(text, 0, len, widths); 106 float width = 0; 107 for (int i = 0; i < count; i++) { 108 width += widths[i]; 109 } 110 return width; 111 } 112 113 // Background state set 114 private static final int[][][] KEY_PREVIEW_BACKGROUND_STATE_TABLE = { 115 { // POSITION_MIDDLE 116 {}, 117 { R.attr.state_has_morekeys } 118 }, 119 { // POSITION_LEFT 120 { R.attr.state_left_edge }, 121 { R.attr.state_left_edge, R.attr.state_has_morekeys } 122 }, 123 { // POSITION_RIGHT 124 { R.attr.state_right_edge }, 125 { R.attr.state_right_edge, R.attr.state_has_morekeys } 126 } 127 }; 128 private static final int STATE_NORMAL = 0; 129 private static final int STATE_HAS_MOREKEYS = 1; 130 setPreviewBackground(final boolean hasMoreKeys, final int position)131 public void setPreviewBackground(final boolean hasMoreKeys, final int position) { 132 final Drawable background = getBackground(); 133 if (background == null) { 134 return; 135 } 136 final int hasMoreKeysState = hasMoreKeys ? STATE_HAS_MOREKEYS : STATE_NORMAL; 137 background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[position][hasMoreKeysState]); 138 } 139 } 140