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.XmlParseUtils;
     25 
     26 import org.xmlpull.v1.XmlPullParser;
     27 import org.xmlpull.v1.XmlPullParserException;
     28 
     29 import java.util.Arrays;
     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 = new HashMap<>();
     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 = new SparseArray<>();
     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                 final String[] array = (String[])value;
     94                 return Arrays.copyOf(array, array.length);
     95             }
     96             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
     97             return parentStyle.getStringArray(a, index);
     98         }
     99 
    100         @Override
    101         public String getString(final TypedArray a, final int index) {
    102             if (a.hasValue(index)) {
    103                 return parseString(a, index);
    104             }
    105             final Object value = mStyleAttributes.get(index);
    106             if (value != null) {
    107                 return (String)value;
    108             }
    109             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    110             return parentStyle.getString(a, index);
    111         }
    112 
    113         @Override
    114         public int getInt(final TypedArray a, final int index, final int defaultValue) {
    115             if (a.hasValue(index)) {
    116                 return a.getInt(index, defaultValue);
    117             }
    118             final Object value = mStyleAttributes.get(index);
    119             if (value != null) {
    120                 return (Integer)value;
    121             }
    122             final KeyStyle parentStyle = mStyles.get(mParentStyleName);
    123             return parentStyle.getInt(a, index, defaultValue);
    124         }
    125 
    126         @Override
    127         public int getFlags(final TypedArray a, final int index) {
    128             final int parentFlags = mStyles.get(mParentStyleName).getFlags(a, index);
    129             final Integer value = (Integer)mStyleAttributes.get(index);
    130             final int styleFlags = (value != null) ? value : 0;
    131             final int flags = a.getInt(index, 0);
    132             return flags | styleFlags | parentFlags;
    133         }
    134 
    135         public void readKeyAttributes(final TypedArray keyAttr) {
    136             // TODO: Currently not all Key attributes can be declared as style.
    137             readString(keyAttr, R.styleable.Keyboard_Key_altCode);
    138             readString(keyAttr, R.styleable.Keyboard_Key_keySpec);
    139             readString(keyAttr, R.styleable.Keyboard_Key_keyHintLabel);
    140             readStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
    141             readStringArray(keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
    142             readFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
    143             readString(keyAttr, R.styleable.Keyboard_Key_keyIconDisabled);
    144             readInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn);
    145             readInt(keyAttr, R.styleable.Keyboard_Key_backgroundType);
    146             readFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
    147         }
    148 
    149         private void readString(final TypedArray a, final int index) {
    150             if (a.hasValue(index)) {
    151                 mStyleAttributes.put(index, parseString(a, index));
    152             }
    153         }
    154 
    155         private void readInt(final TypedArray a, final int index) {
    156             if (a.hasValue(index)) {
    157                 mStyleAttributes.put(index, a.getInt(index, 0));
    158             }
    159         }
    160 
    161         private void readFlags(final TypedArray a, final int index) {
    162             if (a.hasValue(index)) {
    163                 final Integer value = (Integer)mStyleAttributes.get(index);
    164                 final int styleFlags = value != null ? value : 0;
    165                 mStyleAttributes.put(index, a.getInt(index, 0) | styleFlags);
    166             }
    167         }
    168 
    169         private void readStringArray(final TypedArray a, final int index) {
    170             if (a.hasValue(index)) {
    171                 mStyleAttributes.put(index, parseStringArray(a, index));
    172             }
    173         }
    174     }
    175 
    176     public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
    177             final XmlPullParser parser) throws XmlPullParserException {
    178         final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
    179         if (DEBUG) {
    180             Log.d(TAG, String.format("<%s styleName=%s />",
    181                     KeyboardBuilder.TAG_KEY_STYLE, styleName));
    182             if (mStyles.containsKey(styleName)) {
    183                 Log.d(TAG, "key-style " + styleName + " is overridden at "
    184                         + parser.getPositionDescription());
    185             }
    186         }
    187 
    188         String parentStyleName = EMPTY_STYLE_NAME;
    189         if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
    190             parentStyleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_parentStyle);
    191             if (!mStyles.containsKey(parentStyleName)) {
    192                 throw new XmlParseUtils.ParseException(
    193                         "Unknown parentStyle " + parentStyleName, parser);
    194             }
    195         }
    196         final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName, mTextsSet, mStyles);
    197         style.readKeyAttributes(keyAttrs);
    198         mStyles.put(styleName, style);
    199     }
    200 
    201     public KeyStyle getKeyStyle(final TypedArray keyAttr, final XmlPullParser parser)
    202             throws XmlParseUtils.ParseException {
    203         if (!keyAttr.hasValue(R.styleable.Keyboard_Key_keyStyle)) {
    204             return mEmptyKeyStyle;
    205         }
    206         final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
    207         if (!mStyles.containsKey(styleName)) {
    208             throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
    209         }
    210         return mStyles.get(styleName);
    211     }
    212 }
    213