Home | History | Annotate | Download | only in internal
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * 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, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.android.inputmethod.keyboard.internal;
     18 
     19 import android.content.res.TypedArray;
     20 import android.util.Log;
     21 
     22 import com.android.inputmethod.keyboard.Keyboard;
     23 import com.android.inputmethod.latin.R;
     24 import com.android.inputmethod.latin.XmlParseUtils;
     25 
     26 import org.xmlpull.v1.XmlPullParser;
     27 import org.xmlpull.v1.XmlPullParserException;
     28 
     29 import java.util.HashMap;
     30 
     31 public class KeyStyles {
     32     private static final String TAG = KeyStyles.class.getSimpleName();
     33     private static final boolean DEBUG = false;
     34 
     35     final HashMap<String, KeyStyle> mStyles = new HashMap<String, KeyStyle>();
     36 
     37     final KeyboardTextsSet mTextsSet;
     38     private final KeyStyle mEmptyKeyStyle;
     39     private static final String EMPTY_STYLE_NAME = "<empty>";
     40 
     41     public KeyStyles(KeyboardTextsSet textsSet) {
     42         mTextsSet = textsSet;
     43         mEmptyKeyStyle = new EmptyKeyStyle();
     44         mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
     45     }
     46 
     47     public abstract class KeyStyle {
     48         public abstract String[] getStringArray(TypedArray a, int index);
     49         public abstract String getString(TypedArray a, int index);
     50         public abstract int getInt(TypedArray a, int index, int defaultValue);
     51         public abstract int getFlag(TypedArray a, int index);
     52 
     53         protected String parseString(TypedArray a, int index) {
     54             if (a.hasValue(index)) {
     55                 return KeySpecParser.resolveTextReference(a.getString(index), mTextsSet);
     56             }
     57             return null;
     58         }
     59 
     60         protected String[] parseStringArray(TypedArray a, int index) {
     61             if (a.hasValue(index)) {
     62                 return KeySpecParser.parseCsvString(a.getString(index), mTextsSet);
     63             }
     64             return null;
     65         }
     66     }
     67 
     68     class EmptyKeyStyle extends KeyStyle {
     69         @Override
     70         public String[] getStringArray(TypedArray a, int index) {
     71             return parseStringArray(a, index);
     72         }
     73 
     74         @Override
     75         public String getString(TypedArray a, int index) {
     76             return parseString(a, index);
     77         }
     78 
     79         @Override
     80         public int getInt(TypedArray a, int index, int defaultValue) {
     81             return a.getInt(index, defaultValue);
     82         }
     83 
     84         @Override
     85         public int getFlag(TypedArray a, int index) {
     86             return a.getInt(index, 0);
     87         }
     88     }
     89 
     90     private class DeclaredKeyStyle extends KeyStyle {
     91         private final String mParentStyleName;
     92         private final HashMap<Integer, Object> mStyleAttributes = new HashMap<Integer, Object>();
     93 
     94         public DeclaredKeyStyle(String parentStyleName) {
     95             mParentStyleName = parentStyleName;
     96         }
     97 
     98         @Override
     99         public String[] getStringArray(TypedArray a, int index) {
    100             if (a.hasValue(index)) {
    101                 return parseStringArray(a, index);
    102             }
    103             if (mStyleAttributes.containsKey(index)) {
    104                 return (String[])mStyleAttributes.get(index);
    105             }
    106             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    107             return parentStyle.getStringArray(a, index);
    108         }
    109 
    110         @Override
    111         public String getString(TypedArray a, int index) {
    112             if (a.hasValue(index)) {
    113                 return parseString(a, index);
    114             }
    115             if (mStyleAttributes.containsKey(index)) {
    116                 return (String)mStyleAttributes.get(index);
    117             }
    118             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    119             return parentStyle.getString(a, index);
    120         }
    121 
    122         @Override
    123         public int getInt(TypedArray a, int index, int defaultValue) {
    124             if (a.hasValue(index)) {
    125                 return a.getInt(index, defaultValue);
    126             }
    127             if (mStyleAttributes.containsKey(index)) {
    128                 return (Integer)mStyleAttributes.get(index);
    129             }
    130             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    131             return parentStyle.getInt(a, index, defaultValue);
    132         }
    133 
    134         @Override
    135         public int getFlag(TypedArray a, int index) {
    136             int value = a.getInt(index, 0);
    137             if (mStyleAttributes.containsKey(index)) {
    138                 value |= (Integer)mStyleAttributes.get(index);
    139             }
    140             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    141             return value | parentStyle.getFlag(a, index);
    142         }
    143 
    144         void readKeyAttributes(TypedArray keyAttr) {
    145             // TODO: Currently not all Key attributes can be declared as style.
    146             readString(keyAttr, R.styleable.Keyboard_Key_code);
    147             readString(keyAttr, R.styleable.Keyboard_Key_altCode);
    148             readString(keyAttr, R.styleable.Keyboard_Key_keyLabel);
    149             readString(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
    150             readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
    151             readStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
    152             readStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
    153             readFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
    154             readString(keyAttr, R.styleable.Keyboard_Key_keyIcon);
    155             readString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled);
    156             readString(keyAttr, R.styleable.Keyboard_Key_keyIconPreview);
    157             readInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn);
    158             readInt(keyAttr, R.styleable.Keyboard_Key_backgroundType);
    159             readFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
    160         }
    161 
    162         private void readString(TypedArray a, int index) {
    163             if (a.hasValue(index)) {
    164                 mStyleAttributes.put(index, parseString(a, index));
    165             }
    166         }
    167 
    168         private void readInt(TypedArray a, int index) {
    169             if (a.hasValue(index)) {
    170                 mStyleAttributes.put(index, a.getInt(index, 0));
    171             }
    172         }
    173 
    174         private void readFlag(TypedArray a, int index) {
    175             if (a.hasValue(index)) {
    176                 final Integer value = (Integer)mStyleAttributes.get(index);
    177                 mStyleAttributes.put(index, a.getInt(index, 0) | (value != null ? value : 0));
    178             }
    179         }
    180 
    181         private void readStringArray(TypedArray a, int index) {
    182             if (a.hasValue(index)) {
    183                 mStyleAttributes.put(index, parseStringArray(a, index));
    184             }
    185         }
    186     }
    187 
    188     public void parseKeyStyleAttributes(TypedArray keyStyleAttr, TypedArray keyAttrs,
    189             XmlPullParser parser) throws XmlPullParserException {
    190         final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
    191         if (DEBUG) {
    192             Log.d(TAG, String.format("<%s styleName=%s />",
    193                     Keyboard.Builder.TAG_KEY_STYLE, styleName));
    194             if (mStyles.containsKey(styleName)) {
    195                 Log.d(TAG, "key-style " + styleName + " is overridden at "
    196                         + parser.getPositionDescription());
    197             }
    198         }
    199 
    200         String parentStyleName = EMPTY_STYLE_NAME;
    201         if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
    202             parentStyleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_parentStyle);
    203             if (!mStyles.containsKey(parentStyleName)) {
    204                 throw new XmlParseUtils.ParseException(
    205                         "Unknown parentStyle " + parentStyleName, parser);
    206             }
    207         }
    208         final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName);
    209         style.readKeyAttributes(keyAttrs);
    210         mStyles.put(styleName, style);
    211     }
    212 
    213     public KeyStyle getKeyStyle(TypedArray keyAttr, XmlPullParser parser)
    214             throws XmlParseUtils.ParseException {
    215         if (!keyAttr.hasValue(R.styleable.Keyboard_Key_keyStyle)) {
    216             return mEmptyKeyStyle;
    217         }
    218         final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
    219         if (!mStyles.containsKey(styleName)) {
    220             throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
    221         }
    222         return mStyles.get(styleName);
    223     }
    224 }
    225