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