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 KeyStyles(KeyboardTextsSet textsSet)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 { getStringArray(TypedArray a, int index)48 public abstract String[] getStringArray(TypedArray a, int index); getString(TypedArray a, int index)49 public abstract String getString(TypedArray a, int index); getInt(TypedArray a, int index, int defaultValue)50 public abstract int getInt(TypedArray a, int index, int defaultValue); getFlag(TypedArray a, int index)51 public abstract int getFlag(TypedArray a, int index); 52 parseString(TypedArray a, int index)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 parseStringArray(TypedArray a, int index)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 getStringArray(TypedArray a, int index)70 public String[] getStringArray(TypedArray a, int index) { 71 return parseStringArray(a, index); 72 } 73 74 @Override getString(TypedArray a, int index)75 public String getString(TypedArray a, int index) { 76 return parseString(a, index); 77 } 78 79 @Override getInt(TypedArray a, int index, int defaultValue)80 public int getInt(TypedArray a, int index, int defaultValue) { 81 return a.getInt(index, defaultValue); 82 } 83 84 @Override getFlag(TypedArray a, int index)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 DeclaredKeyStyle(String parentStyleName)94 public DeclaredKeyStyle(String parentStyleName) { 95 mParentStyleName = parentStyleName; 96 } 97 98 @Override getStringArray(TypedArray a, int index)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 getString(TypedArray a, int index)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 getInt(TypedArray a, int index, int defaultValue)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 getFlag(TypedArray a, int index)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 readKeyAttributes(TypedArray keyAttr)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 readString(TypedArray a, int index)162 private void readString(TypedArray a, int index) { 163 if (a.hasValue(index)) { 164 mStyleAttributes.put(index, parseString(a, index)); 165 } 166 } 167 readInt(TypedArray a, int index)168 private void readInt(TypedArray a, int index) { 169 if (a.hasValue(index)) { 170 mStyleAttributes.put(index, a.getInt(index, 0)); 171 } 172 } 173 readFlag(TypedArray a, int index)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 readStringArray(TypedArray a, int index)181 private void readStringArray(TypedArray a, int index) { 182 if (a.hasValue(index)) { 183 mStyleAttributes.put(index, parseStringArray(a, index)); 184 } 185 } 186 } 187 parseKeyStyleAttributes(TypedArray keyStyleAttr, TypedArray keyAttrs, XmlPullParser parser)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 getKeyStyle(TypedArray keyAttr, XmlPullParser parser)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