Home | History | Annotate | Download | only in internal
      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 
     45     public KeyPreviewView(final Context context, final AttributeSet attrs) {
     46         this(context, attrs, 0);
     47     }
     48 
     49     public KeyPreviewView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
     50         super(context, attrs, defStyleAttr);
     51         setGravity(Gravity.CENTER);
     52     }
     53 
     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 
     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 
     95     public static void clearTextCache() {
     96         sNoScaleXTextSet.clear();
     97     }
     98 
     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 
    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