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