1c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka/* 2c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project 3c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * 48aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 58aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * you may not use this file except in compliance with the License. 68aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * You may obtain a copy of the License at 7c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka * 88aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi 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 118aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 128aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * See the License for the specific language governing permissions and 148aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * limitations under 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 25c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokaimport com.android.inputmethod.latin.R; 26e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.utils.CollectionUtils; 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, 59b127d882854d81a47473b344a1e5f277866bbf22Tadashi G. Takaoka "emoji_key", R.styleable.Keyboard_iconEmojiKey, 60cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka }; 61cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka 62cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2; 63cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private static final String[] ICON_NAMES = new String[NUM_ICONS]; 64cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka private final Drawable[] mIcons = new Drawable[NUM_ICONS]; 65c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 66cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka static { 67cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka int iconId = ICON_UNDEFINED; 68cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka for (int i = 0; i < NAMES_AND_ATTR_IDS.length; i += 2) { 69cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka final String name = (String)NAMES_AND_ATTR_IDS[i]; 70cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka final Integer attrId = (Integer)NAMES_AND_ATTR_IDS[i + 1]; 71cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka if (attrId != ATTR_UNDEFINED) { 72cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka ATTR_ID_TO_ICON_ID.put(attrId, iconId); 73cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka } 740a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka sNameToIdsMap.put(name, iconId); 75cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka ICON_NAMES[iconId] = name; 76cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka iconId++; 77e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka } 78c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 79c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 80b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka public void loadIcons(final TypedArray keyboardAttrs) { 8156853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka final int size = ATTR_ID_TO_ICON_ID.size(); 8256853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka for (int index = 0; index < size; index++) { 8356853c1e48deb71367104060b49b7b1f0344a476Tadashi G. Takaoka final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index); 8442fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka try { 8542fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka final Drawable icon = keyboardAttrs.getDrawable(attrId); 8642fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka setDefaultBounds(icon); 87e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId); 88e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka mIcons[iconId] = icon; 8942fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka } catch (Resources.NotFoundException e) { 9042fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka Log.w(TAG, "Drawable resource for icon #" 9142fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka + keyboardAttrs.getResources().getResourceEntryName(attrId) 9242fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka + " not found"); 93c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 94c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 95c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 96c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka 97e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka private static boolean isValidIconId(final int iconId) { 98e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return iconId >= 0 && iconId < ICON_NAMES.length; 99b009a24b838b560bd093ff295c99c0cf5fe27c81Tadashi G. Takaoka } 100b009a24b838b560bd093ff295c99c0cf5fe27c81Tadashi G. Takaoka 101e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka public static String getIconName(final int iconId) { 102e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">"; 10342fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka } 10442fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka 105cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka static int getIconId(final String name) { 1060a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka Integer iconId = sNameToIdsMap.get(name); 107e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka if (iconId != null) { 108e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return iconId; 10944e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka } 110e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka throw new RuntimeException("unknown icon name: " + name); 11144e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka } 11244e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka 113e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka public Drawable getIconDrawable(final int iconId) { 114e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka if (isValidIconId(iconId)) { 115e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka return mIcons[iconId]; 11642fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka } 117e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka throw new RuntimeException("unknown icon id: " + getIconName(iconId)); 118c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka } 119b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka 120e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka private static void setDefaultBounds(final Drawable icon) { 121b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka if (icon != null) { 122b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); 123b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka } 124b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka } 125c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka} 126