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.CollectionUtils;
     24 import com.android.inputmethod.latin.R;
     25 import com.android.inputmethod.latin.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 getFlag(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 getFlag(final TypedArray a, final int index) {
    127             int flags = a.getInt(index, 0);
    128             final Object value = mStyleAttributes.get(index);
    129             if (value != null) {
    130                 flags |= (Integer)value;
    131             }
    132             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    133             return flags | parentStyle.getFlag(a, index);
    134         }
    135 
    136         public void readKeyAttributes(final TypedArray keyAttr) {
    137             // TODO: Currently not all Key attributes can be declared as style.
    138             readString(keyAttr, R.styleable.Keyboard_Key_code);
    139             readString(keyAttr, R.styleable.Keyboard_Key_altCode);
    140             readString(keyAttr, R.styleable.Keyboard_Key_keyLabel);
    141             readString(keyAttr, R.styleable.Keyboard_Key_keyOutputText);
    142             readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
    143             readStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
    144             readStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
    145             readFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
    146             readString(keyAttr, R.styleable.Keyboard_Key_keyIcon);
    147             readString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled);
    148             readString(keyAttr, R.styleable.Keyboard_Key_keyIconPreview);
    149             readInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn);
    150             readInt(keyAttr, R.styleable.Keyboard_Key_backgroundType);
    151             readFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
    152         }
    153 
    154         private void readString(final TypedArray a, final int index) {
    155             if (a.hasValue(index)) {
    156                 mStyleAttributes.put(index, parseString(a, index));
    157             }
    158         }
    159 
    160         private void readInt(final TypedArray a, final int index) {
    161             if (a.hasValue(index)) {
    162                 mStyleAttributes.put(index, a.getInt(index, 0));
    163             }
    164         }
    165 
    166         private void readFlag(final TypedArray a, final int index) {
    167             if (a.hasValue(index)) {
    168                 final Integer value = (Integer)mStyleAttributes.get(index);
    169                 mStyleAttributes.put(index, a.getInt(index, 0) | (value != null ? value : 0));
    170             }
    171         }
    172 
    173         private void readStringArray(final TypedArray a, final int index) {
    174             if (a.hasValue(index)) {
    175                 mStyleAttributes.put(index, parseStringArray(a, index));
    176             }
    177         }
    178     }
    179 
    180     public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
    181             final XmlPullParser parser) throws XmlPullParserException {
    182         final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
    183         if (DEBUG) {
    184             Log.d(TAG, String.format("<%s styleName=%s />",
    185                     KeyboardBuilder.TAG_KEY_STYLE, styleName));
    186             if (mStyles.containsKey(styleName)) {
    187                 Log.d(TAG, "key-style " + styleName + " is overridden at "
    188                         + parser.getPositionDescription());
    189             }
    190         }
    191 
    192         String parentStyleName = EMPTY_STYLE_NAME;
    193         if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
    194             parentStyleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_parentStyle);
    195             if (!mStyles.containsKey(parentStyleName)) {
    196                 throw new XmlParseUtils.ParseException(
    197                         "Unknown parentStyle " + parentStyleName, parser);
    198             }
    199         }
    200         final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName, mTextsSet, mStyles);
    201         style.readKeyAttributes(keyAttrs);
    202         mStyles.put(styleName, style);
    203     }
    204 
    205     public KeyStyle getKeyStyle(final TypedArray keyAttr, final XmlPullParser parser)
    206             throws XmlParseUtils.ParseException {
    207         if (!keyAttr.hasValue(R.styleable.Keyboard_Key_keyStyle)) {
    208             return mEmptyKeyStyle;
    209         }
    210         final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
    211         if (!mStyles.containsKey(styleName)) {
    212             throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
    213         }
    214         return mStyles.get(styleName);
    215     }
    216 }
    217