1c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka/* 2c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project 3c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * 4c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * use this file except in compliance with the License. You may obtain a copy of 6c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * the License at 7c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * 8c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * 10c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 11c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * License for the specific language governing permissions and limitations under 14c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * the License. 15c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka */ 16c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 17c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokapackage com.android.inputmethod.keyboard.internal; 18c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 19a93d27d6b87c29cb6292d1dd1223a4e42cca07d9Tadashi G. Takaokaimport android.content.res.Resources; 20c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokaimport android.content.res.TypedArray; 21c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokaimport android.graphics.drawable.Drawable; 22a93d27d6b87c29cb6292d1dd1223a4e42cca07d9Tadashi G. Takaokaimport android.util.Log; 2356853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaokaimport android.util.SparseIntArray; 24c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 255f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaokaimport com.android.inputmethod.latin.CollectionUtils; 26c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokaimport com.android.inputmethod.latin.R; 27c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 2842fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaokaimport java.util.HashMap; 2942fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka 30a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaokapublic final class KeyboardIconsSet { 31a93d27d6b87c29cb6292d1dd1223a4e42cca07d9Tadashi G. Takaoka private static final String TAG = KeyboardIconsSet.class.getSimpleName(); 32a93d27d6b87c29cb6292d1dd1223a4e42cca07d9Tadashi G. Takaoka 33b19a6b9fc55910bd241bee3b312169a818cb721dTadashi G. Takaoka public static final int ICON_UNDEFINED = 0; 34cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private static final int ATTR_UNDEFINED = 0; 35c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 3656853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray(); 37cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka 380a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka // Icon name to icon id map. 395f282ea9e4a4590fcbab6e27d5fca7dacbb40a6aTadashi G. Takaoka private static final HashMap<String, Integer> sNameToIdsMap = CollectionUtils.newHashMap(); 40c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 41cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private static final Object[] NAMES_AND_ATTR_IDS = { 42cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "undefined", ATTR_UNDEFINED, 43cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "shift_key", R.styleable.Keyboard_iconShiftKey, 44cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "delete_key", R.styleable.Keyboard_iconDeleteKey, 45cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "settings_key", R.styleable.Keyboard_iconSettingsKey, 46cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "space_key", R.styleable.Keyboard_iconSpaceKey, 47cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "enter_key", R.styleable.Keyboard_iconEnterKey, 48cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "search_key", R.styleable.Keyboard_iconSearchKey, 49cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "tab_key", R.styleable.Keyboard_iconTabKey, 50cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "shortcut_key", R.styleable.Keyboard_iconShortcutKey, 51cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "shortcut_for_label", R.styleable.Keyboard_iconShortcutForLabel, 52cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "space_key_for_number_layout", R.styleable.Keyboard_iconSpaceKeyForNumberLayout, 53cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "shift_key_shifted", R.styleable.Keyboard_iconShiftKeyShifted, 54cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "shortcut_key_disabled", R.styleable.Keyboard_iconShortcutKeyDisabled, 55cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "tab_key_preview", R.styleable.Keyboard_iconTabKeyPreview, 56cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "language_switch_key", R.styleable.Keyboard_iconLanguageSwitchKey, 57cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "zwnj_key", R.styleable.Keyboard_iconZwnjKey, 58cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka "zwj_key", R.styleable.Keyboard_iconZwjKey, 59cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka }; 60cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka 61cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2; 62cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private static final String[] ICON_NAMES = new String[NUM_ICONS]; 63cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private final Drawable[] mIcons = new Drawable[NUM_ICONS]; 64c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 65cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka static { 66cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka int iconId = ICON_UNDEFINED; 67cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka for (int i = 0; i < NAMES_AND_ATTR_IDS.length; i += 2) { 68cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka final String name = (String)NAMES_AND_ATTR_IDS[i]; 69cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka final Integer attrId = (Integer)NAMES_AND_ATTR_IDS[i + 1]; 70cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka if (attrId != ATTR_UNDEFINED) { 71cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka ATTR_ID_TO_ICON_ID.put(attrId, iconId); 72cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka } 730a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka sNameToIdsMap.put(name, iconId); 74cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka ICON_NAMES[iconId] = name; 75cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka iconId++; 76e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka } 77c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 78c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 79b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka public void loadIcons(final TypedArray keyboardAttrs) { 8056853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka final int size = ATTR_ID_TO_ICON_ID.size(); 8156853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka for (int index = 0; index < size; index++) { 8256853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index); 8342fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka try { 8442fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka final Drawable icon = keyboardAttrs.getDrawable(attrId); 8542fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka setDefaultBounds(icon); 86e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId); 87e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka mIcons[iconId] = icon; 8842fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka } catch (Resources.NotFoundException e) { 8942fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka Log.w(TAG, "Drawable resource for icon #" 9042fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka + keyboardAttrs.getResources().getResourceEntryName(attrId) 9142fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka + " not found"); 92c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 93c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 94c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 95c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 96e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka private static boolean isValidIconId(final int iconId) { 97e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return iconId >= 0 && iconId < ICON_NAMES.length; 98b009a24b838b560bd093ff295c99c0cf5fe27c81Tadashi G. Takaoka } 99b009a24b838b560bd093ff295c99c0cf5fe27c81Tadashi G. Takaoka 100e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka public static String getIconName(final int iconId) { 101e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">"; 10242fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka } 10342fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka 104cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka static int getIconId(final String name) { 1050a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka Integer iconId = sNameToIdsMap.get(name); 106e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka if (iconId != null) { 107e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return iconId; 10844e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka } 109e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka throw new RuntimeException("unknown icon name: " + name); 11044e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka } 11144e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka 112e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka public Drawable getIconDrawable(final int iconId) { 113e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka if (isValidIconId(iconId)) { 114e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return mIcons[iconId]; 11542fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka } 116e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka throw new RuntimeException("unknown icon id: " + getIconName(iconId)); 117c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 118b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka 119e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka private static void setDefaultBounds(final Drawable icon) { 120b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka if (icon != null) { 121b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); 122b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka } 123b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka } 124c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka} 125