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");
      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.res.TypedArray;
     20 import android.util.Log;
     21 import android.util.SparseArray;
     22 
     23 import com.android.inputmethod.latin.R;
     24 import com.android.inputmethod.latin.utils.CollectionUtils;
     25 import com.android.inputmethod.latin.utils.XmlParseUtils;
     26 
     27 import org.xmlpull.v1.XmlPullParser;
     28 import org.xmlpull.v1.XmlPullParserException;
     29 
     30 import java.util.HashMap;
     31 
     32 public final class KeyStylesSet {
     33     private static final String TAG = KeyStylesSet.class.getSimpleName();
     34     private static final boolean DEBUG = false;
     35 
     36     private final HashMap<String, KeyStyle> mStyles = CollectionUtils.newHashMap();
     37 
     38     private final KeyboardTextsSet mTextsSet;
     39     private final KeyStyle mEmptyKeyStyle;
     40     private static final String EMPTY_STYLE_NAME = "<empty>";
     41 
     42     public KeyStylesSet(final KeyboardTextsSet textsSet) {
     43         mTextsSet = textsSet;
     44         mEmptyKeyStyle = new EmptyKeyStyle(textsSet);
     45         mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
     46     }
     47 
     48     private static final class EmptyKeyStyle extends KeyStyle {
     49         EmptyKeyStyle(final KeyboardTextsSet textsSet) {
     50             super(textsSet);
     51         }
     52 
     53         @Override
     54         public String[] getStringArray(final TypedArray a, final int index) {
     55             return parseStringArray(a, index);
     56         }
     57 
     58         @Override
     59         public String getString(final TypedArray a, final int index) {
     60             return parseString(a, index);
     61         }
     62 
     63         @Override
     64         public int getInt(final TypedArray a, final int index, final int defaultValue) {
     65             return a.getInt(index, defaultValue);
     66         }
     67 
     68         @Override
     69         public int getFlags(final TypedArray a, final int index) {
     70             return a.getInt(index, 0);
     71         }
     72     }
     73 
     74     private static final class DeclaredKeyStyle extends KeyStyle {
     75         private final HashMap<String, KeyStyle> mStyles;
     76         private final String mParentStyleName;
     77         private final SparseArray<Object> mStyleAttributes = CollectionUtils.newSparseArray();
     78 
     79         public DeclaredKeyStyle(final String parentStyleName, final KeyboardTextsSet textsSet,
     80                 final HashMap<String, KeyStyle> styles) {
     81             super(textsSet);
     82             mParentStyleName = parentStyleName;
     83             mStyles = styles;
     84         }
     85 
     86         @Override
     87         public String[] getStringArray(final TypedArray a, final int index) {
     88             if (a.hasValue(index)) {
     89                 return parseStringArray(a, index);
     90             }
     91             final Object value = mStyleAttributes.get(index);
     92             if (value != null) {
     93                 return (String[])value;
     94             }
     95             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
     96             return parentStyle.getStringArray(a, index);
     97         }
     98 
     99         @Override
    100         public String getString(final TypedArray a, final int index) {
    101             if (a.hasValue(index)) {
    102                 return parseString(a, index);
    103             }
    104             final Object value = mStyleAttributes.get(index);
    105             if (value != null) {
    106                 return (String)value;
    107             }
    108             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    109             return parentStyle.getString(a, index);
    110         }
    111 
    112         @Override
    113         public int getInt(final TypedArray a, final int index, final int defaultValue) {
    114             if (a.hasValue(index)) {
    115                 return a.getInt(index, defaultValue);
    116             }
    117             final Object value = mStyleAttributes.get(index);
    118             if (value != null) {
    119                 return (Integer)value;
    120             }
    121             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    122             return parentStyle.getInt(a, index, defaultValue);
    123         }
    124 
    125         @Override
    126         public int getFlags(final TypedArray a, final int index) {
    127             final int parentFlags = mStyles.get(mParentStyleName).getFlags(a, index);
    128             final Integer value = (Integer)mStyleAttributes.get(index);
    129             final int styleFlags = (value != null) ? value : 0;
    130             final int flags = a.getInt(index, 0);
    131             return flags | styleFlags | parentFlags;
    132         }
    133 
    134         public void readKeyAttributes(final TypedArray keyAttr) {
    135             // TODO: Currently not all Key attributes can be declared as style.
    136             readString(keyAttr, R.styleable.Keyboard_Key_code);
    137             readString(keyAttr, R.styleable.Keyboard_Key_altCode);
    138             readString(keyAttr, R.styleable.Keyboard_Key_keyLabel);
    139             readString(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
    140             readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
    141             readStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
    142             readStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
    143             readFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
    144             readString(keyAttr, R.styleable.Keyboard_Key_keyIcon);
    145             readString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled);
    146             readString(keyAttr, R.styleable.Keyboard_Key_keyIconPreview);
    147             readInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn);
    148             readInt(keyAttr, R.styleable.Keyboard_Key_backgroundType);
    149             readFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
    150         }
    151 
    152         private void readString(final TypedArray a, final int index) {
    153             if (a.hasValue(index)) {
    154                 mStyleAttributes.put(index, parseString(a, index));
    155             }
    156         }
    157 
    158         private void readInt(final TypedArray a, final int index) {
    159             if (a.hasValue(index)) {
    160                 mStyleAttributes.put(index, a.getInt(index, 0));
    161             }
    162         }
    163 
    164         private void readFlags(final TypedArray a, final int index) {
    165             if (a.hasValue(index)) {
    166                 final Integer value = (Integer)mStyleAttributes.get(index);
    167                 final int styleFlags = value != null ? value : 0;
    168                 mStyleAttributes.put(index, a.getInt(index, 0) | styleFlags);
    169             }
    170         }
    171 
    172         private void readStringArray(final TypedArray a, final int index) {
    173             if (a.hasValue(index)) {
    174                 mStyleAttributes.put(index, parseStringArray(a, index));
    175             }
    176         }
    177     }
    178 
    179     public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
    180             final XmlPullParser parser) throws XmlPullParserException {
    181         final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
    182         if (DEBUG) {
    183             Log.d(TAG, String.format("<%s styleName=%s />",
    184                     KeyboardBuilder.TAG_KEY_STYLE, styleName));
    185             if (mStyles.containsKey(styleName)) {
    186                 Log.d(TAG, "key-style " + styleName + " is overridden at "
    187                         + parser.getPositionDescription());
    188             }
    189         }
    190 
    191         String parentStyleName = EMPTY_STYLE_NAME;
    192         if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
    193             parentStyleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_parentStyle);
    194             if (!mStyles.containsKey(parentStyleName)) {
    195                 throw new XmlParseUtils.ParseException(
    196                         "Unknown parentStyle " + parentStyleName, parser);
    197             }
    198         }
    199         final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName, mTextsSet, mStyles);
    200         style.readKeyAttributes(keyAttrs);
    201         mStyles.put(styleName, style);
    202     }
    203 
    204     public KeyStyle getKeyStyle(final TypedArray keyAttr, final XmlPullParser parser)
    205             throws XmlParseUtils.ParseException {
    206         if (!keyAttr.hasValue(R.styleable.Keyboard_Key_keyStyle)) {
    207             return mEmptyKeyStyle;
    208         }
    209         final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
    210         if (!mStyles.containsKey(styleName)) {
    211             throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
    212         }
    213         return mStyles.get(styleName);
    214     }
    215 }
    216