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;
23c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
24c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokaimport com.android.inputmethod.latin.R;
25c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
2642fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaokaimport java.util.HashMap;
2742fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka
28c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaokapublic class KeyboardIconsSet {
29a93d27d6b87c29cb6292d1dd1223a4e42cca07d9Tadashi G. Takaoka    private static final String TAG = KeyboardIconsSet.class.getSimpleName();
30a93d27d6b87c29cb6292d1dd1223a4e42cca07d9Tadashi G. Takaoka
31b19a6b9fc55910bd241bee3b312169a818cb721dTadashi G. Takaoka    public static final int ICON_UNDEFINED = 0;
32cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    private static final int ATTR_UNDEFINED = 0;
33c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
34b4fbbe57f574ce6e6a5827156f875fe7d3eb5089Tadashi G. Takaoka    private static final HashMap<Integer, Integer> ATTR_ID_TO_ICON_ID
35b4fbbe57f574ce6e6a5827156f875fe7d3eb5089Tadashi G. Takaoka            = new HashMap<Integer, Integer>();
36cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka
370a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka    // Icon name to icon id map.
380a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka    private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<String, Integer>();
39c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
40cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    private static final Object[] NAMES_AND_ATTR_IDS = {
41cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "undefined",                    ATTR_UNDEFINED,
42cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "shift_key",                    R.styleable.Keyboard_iconShiftKey,
43cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "delete_key",                   R.styleable.Keyboard_iconDeleteKey,
44cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "settings_key",                 R.styleable.Keyboard_iconSettingsKey,
45cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "space_key",                    R.styleable.Keyboard_iconSpaceKey,
46cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "enter_key",                    R.styleable.Keyboard_iconEnterKey,
47cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "search_key",                   R.styleable.Keyboard_iconSearchKey,
48cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "tab_key",                      R.styleable.Keyboard_iconTabKey,
49cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "shortcut_key",                 R.styleable.Keyboard_iconShortcutKey,
50cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "shortcut_for_label",           R.styleable.Keyboard_iconShortcutForLabel,
51cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "space_key_for_number_layout",  R.styleable.Keyboard_iconSpaceKeyForNumberLayout,
52cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "shift_key_shifted",            R.styleable.Keyboard_iconShiftKeyShifted,
53cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "shortcut_key_disabled",        R.styleable.Keyboard_iconShortcutKeyDisabled,
54cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "tab_key_preview",              R.styleable.Keyboard_iconTabKeyPreview,
55cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "language_switch_key",          R.styleable.Keyboard_iconLanguageSwitchKey,
56cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "zwnj_key",                     R.styleable.Keyboard_iconZwnjKey,
57cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        "zwj_key",                      R.styleable.Keyboard_iconZwjKey,
58cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    };
59cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka
60cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2;
61cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    private static final String[] ICON_NAMES = new String[NUM_ICONS];
62cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    private final Drawable[] mIcons = new Drawable[NUM_ICONS];
63c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
64cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    static {
65cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        int iconId = ICON_UNDEFINED;
66cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka        for (int i = 0; i < NAMES_AND_ATTR_IDS.length; i += 2) {
67cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka            final String name = (String)NAMES_AND_ATTR_IDS[i];
68cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka            final Integer attrId = (Integer)NAMES_AND_ATTR_IDS[i + 1];
69cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka            if (attrId != ATTR_UNDEFINED) {
70cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka                ATTR_ID_TO_ICON_ID.put(attrId,  iconId);
71cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka            }
720a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka            sNameToIdsMap.put(name, iconId);
73cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka            ICON_NAMES[iconId] = name;
74cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka            iconId++;
75e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        }
76c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka    }
77c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
78b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka    public void loadIcons(final TypedArray keyboardAttrs) {
79e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        for (final Integer attrId : ATTR_ID_TO_ICON_ID.keySet()) {
8042fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka            try {
8142fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka                final Drawable icon = keyboardAttrs.getDrawable(attrId);
8242fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka                setDefaultBounds(icon);
83e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka                final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId);
84e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka                mIcons[iconId] = icon;
8542fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka            } catch (Resources.NotFoundException e) {
8642fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka                Log.w(TAG, "Drawable resource for icon #"
8742fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka                        + keyboardAttrs.getResources().getResourceEntryName(attrId)
8842fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka                        + " not found");
89c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka            }
90c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka        }
91c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka    }
92c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka
93e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka    private static boolean isValidIconId(final int iconId) {
94e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        return iconId >= 0 && iconId < ICON_NAMES.length;
95b009a24b838b560bd093ff295c99c0cf5fe27c81Tadashi G. Takaoka    }
96b009a24b838b560bd093ff295c99c0cf5fe27c81Tadashi G. Takaoka
97e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka    public static String getIconName(final int iconId) {
98e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
9942fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka    }
10042fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka
101cf41aff251ecc94b729307ede05208a104fcd8b0Tadashi G. Takaoka    static int getIconId(final String name) {
1020a3362d26474cbd60bf870be7ad1413359e4fad6Tadashi G. Takaoka        Integer iconId = sNameToIdsMap.get(name);
103e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        if (iconId != null) {
104e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka            return iconId;
10544e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka        }
106e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        throw new RuntimeException("unknown icon name: " + name);
10744e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka    }
10844e0e4f99e70b84176ff5c985e456b821a8f0b14Tadashi G. Takaoka
109e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka    public Drawable getIconDrawable(final int iconId) {
110e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        if (isValidIconId(iconId)) {
111e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka            return mIcons[iconId];
11242fcb2de641c4cd5d57f34889c8752401e35dcc8Tadashi G. Takaoka        }
113e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka        throw new RuntimeException("unknown icon id: " + getIconName(iconId));
114c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka    }
115b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka
116e7948a8692a102c89aca70a79ca62573d77efde3Tadashi G. Takaoka    private static void setDefaultBounds(final Drawable icon)  {
117b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka        if (icon != null) {
118b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka            icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
119b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka        }
120b118d4cb58c27131f6333ada281c772edfcaa74bTadashi G. Takaoka    }
121c2a21786e526cc32e48a577a55b1b7e72ae1a6ddTadashi G. Takaoka}
122