1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.inputmethod.keyboard.internal; 18 19 import android.content.res.Resources; 20 import android.content.res.TypedArray; 21 import android.graphics.drawable.Drawable; 22 import android.util.Log; 23 import android.util.SparseIntArray; 24 25 import com.android.inputmethod.latin.R; 26 27 import java.util.HashMap; 28 29 import javax.annotation.Nonnull; 30 import javax.annotation.Nullable; 31 32 public final class KeyboardIconsSet { 33 private static final String TAG = KeyboardIconsSet.class.getSimpleName(); 34 35 public static final String PREFIX_ICON = "!icon/"; 36 public static final int ICON_UNDEFINED = 0; 37 private static final int ATTR_UNDEFINED = 0; 38 39 private static final String NAME_UNDEFINED = "undefined"; 40 public static final String NAME_SHIFT_KEY = "shift_key"; 41 public static final String NAME_SHIFT_KEY_SHIFTED = "shift_key_shifted"; 42 public static final String NAME_DELETE_KEY = "delete_key"; 43 public static final String NAME_SETTINGS_KEY = "settings_key"; 44 public static final String NAME_SPACE_KEY = "space_key"; 45 public static final String NAME_SPACE_KEY_FOR_NUMBER_LAYOUT = "space_key_for_number_layout"; 46 public static final String NAME_ENTER_KEY = "enter_key"; 47 public static final String NAME_GO_KEY = "go_key"; 48 public static final String NAME_SEARCH_KEY = "search_key"; 49 public static final String NAME_SEND_KEY = "send_key"; 50 public static final String NAME_NEXT_KEY = "next_key"; 51 public static final String NAME_DONE_KEY = "done_key"; 52 public static final String NAME_PREVIOUS_KEY = "previous_key"; 53 public static final String NAME_TAB_KEY = "tab_key"; 54 public static final String NAME_SHORTCUT_KEY = "shortcut_key"; 55 public static final String NAME_SHORTCUT_KEY_DISABLED = "shortcut_key_disabled"; 56 public static final String NAME_LANGUAGE_SWITCH_KEY = "language_switch_key"; 57 public static final String NAME_ZWNJ_KEY = "zwnj_key"; 58 public static final String NAME_ZWJ_KEY = "zwj_key"; 59 public static final String NAME_EMOJI_ACTION_KEY = "emoji_action_key"; 60 public static final String NAME_EMOJI_NORMAL_KEY = "emoji_normal_key"; 61 62 private static final SparseIntArray ATTR_ID_TO_ICON_ID = new SparseIntArray(); 63 64 // Icon name to icon id map. 65 private static final HashMap<String, Integer> sNameToIdsMap = new HashMap<>(); 66 67 private static final Object[] NAMES_AND_ATTR_IDS = { 68 NAME_UNDEFINED, ATTR_UNDEFINED, 69 NAME_SHIFT_KEY, R.styleable.Keyboard_iconShiftKey, 70 NAME_DELETE_KEY, R.styleable.Keyboard_iconDeleteKey, 71 NAME_SETTINGS_KEY, R.styleable.Keyboard_iconSettingsKey, 72 NAME_SPACE_KEY, R.styleable.Keyboard_iconSpaceKey, 73 NAME_ENTER_KEY, R.styleable.Keyboard_iconEnterKey, 74 NAME_GO_KEY, R.styleable.Keyboard_iconGoKey, 75 NAME_SEARCH_KEY, R.styleable.Keyboard_iconSearchKey, 76 NAME_SEND_KEY, R.styleable.Keyboard_iconSendKey, 77 NAME_NEXT_KEY, R.styleable.Keyboard_iconNextKey, 78 NAME_DONE_KEY, R.styleable.Keyboard_iconDoneKey, 79 NAME_PREVIOUS_KEY, R.styleable.Keyboard_iconPreviousKey, 80 NAME_TAB_KEY, R.styleable.Keyboard_iconTabKey, 81 NAME_SHORTCUT_KEY, R.styleable.Keyboard_iconShortcutKey, 82 NAME_SPACE_KEY_FOR_NUMBER_LAYOUT, R.styleable.Keyboard_iconSpaceKeyForNumberLayout, 83 NAME_SHIFT_KEY_SHIFTED, R.styleable.Keyboard_iconShiftKeyShifted, 84 NAME_SHORTCUT_KEY_DISABLED, R.styleable.Keyboard_iconShortcutKeyDisabled, 85 NAME_LANGUAGE_SWITCH_KEY, R.styleable.Keyboard_iconLanguageSwitchKey, 86 NAME_ZWNJ_KEY, R.styleable.Keyboard_iconZwnjKey, 87 NAME_ZWJ_KEY, R.styleable.Keyboard_iconZwjKey, 88 NAME_EMOJI_ACTION_KEY, R.styleable.Keyboard_iconEmojiActionKey, 89 NAME_EMOJI_NORMAL_KEY, R.styleable.Keyboard_iconEmojiNormalKey, 90 }; 91 92 private static int NUM_ICONS = NAMES_AND_ATTR_IDS.length / 2; 93 private static final String[] ICON_NAMES = new String[NUM_ICONS]; 94 private final Drawable[] mIcons = new Drawable[NUM_ICONS]; 95 private final int[] mIconResourceIds = new int[NUM_ICONS]; 96 97 static { 98 int iconId = ICON_UNDEFINED; 99 for (int i = 0; i < NAMES_AND_ATTR_IDS.length; i += 2) { 100 final String name = (String)NAMES_AND_ATTR_IDS[i]; 101 final Integer attrId = (Integer)NAMES_AND_ATTR_IDS[i + 1]; 102 if (attrId != ATTR_UNDEFINED) { 103 ATTR_ID_TO_ICON_ID.put(attrId, iconId); 104 } 105 sNameToIdsMap.put(name, iconId); 106 ICON_NAMES[iconId] = name; 107 iconId++; 108 } 109 } 110 111 public void loadIcons(final TypedArray keyboardAttrs) { 112 final int size = ATTR_ID_TO_ICON_ID.size(); 113 for (int index = 0; index < size; index++) { 114 final int attrId = ATTR_ID_TO_ICON_ID.keyAt(index); 115 try { 116 final Drawable icon = keyboardAttrs.getDrawable(attrId); 117 setDefaultBounds(icon); 118 final Integer iconId = ATTR_ID_TO_ICON_ID.get(attrId); 119 mIcons[iconId] = icon; 120 mIconResourceIds[iconId] = keyboardAttrs.getResourceId(attrId, 0); 121 } catch (Resources.NotFoundException e) { 122 Log.w(TAG, "Drawable resource for icon #" 123 + keyboardAttrs.getResources().getResourceEntryName(attrId) 124 + " not found"); 125 } 126 } 127 } 128 129 private static boolean isValidIconId(final int iconId) { 130 return iconId >= 0 && iconId < ICON_NAMES.length; 131 } 132 133 @Nonnull 134 public static String getIconName(final int iconId) { 135 return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">"; 136 } 137 138 public static int getIconId(final String name) { 139 Integer iconId = sNameToIdsMap.get(name); 140 if (iconId != null) { 141 return iconId; 142 } 143 throw new RuntimeException("unknown icon name: " + name); 144 } 145 146 public int getIconResourceId(final String name) { 147 final int iconId = getIconId(name); 148 if (isValidIconId(iconId)) { 149 return mIconResourceIds[iconId]; 150 } 151 throw new RuntimeException("unknown icon name: " + name); 152 } 153 154 @Nullable 155 public Drawable getIconDrawable(final int iconId) { 156 if (isValidIconId(iconId)) { 157 return mIcons[iconId]; 158 } 159 throw new RuntimeException("unknown icon id: " + getIconName(iconId)); 160 } 161 162 private static void setDefaultBounds(final Drawable icon) { 163 if (icon != null) { 164 icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); 165 } 166 } 167 } 168