1 /* 2 * Copyright (C) 2008-2009 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.inputmethod.latin; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.content.res.XmlResourceParser; 22 import android.graphics.drawable.Drawable; 23 import android.inputmethodservice.Keyboard; 24 import android.view.inputmethod.EditorInfo; 25 26 public class LatinKeyboard extends Keyboard { 27 28 private Drawable mShiftLockIcon; 29 private Drawable mShiftLockPreviewIcon; 30 private Drawable mOldShiftIcon; 31 private Drawable mOldShiftPreviewIcon; 32 private Key mShiftKey; 33 private Key mEnterKey; 34 35 private static final int SHIFT_OFF = 0; 36 private static final int SHIFT_ON = 1; 37 private static final int SHIFT_LOCKED = 2; 38 39 private int mShiftState = SHIFT_OFF; 40 41 static int sSpacebarVerticalCorrection; 42 LatinKeyboard(Context context, int xmlLayoutResId)43 public LatinKeyboard(Context context, int xmlLayoutResId) { 44 this(context, xmlLayoutResId, 0); 45 } 46 LatinKeyboard(Context context, int xmlLayoutResId, int mode)47 public LatinKeyboard(Context context, int xmlLayoutResId, int mode) { 48 super(context, xmlLayoutResId, mode); 49 Resources res = context.getResources(); 50 mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked); 51 mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked); 52 mShiftLockPreviewIcon.setBounds(0, 0, 53 mShiftLockPreviewIcon.getIntrinsicWidth(), 54 mShiftLockPreviewIcon.getIntrinsicHeight()); 55 sSpacebarVerticalCorrection = res.getDimensionPixelOffset( 56 R.dimen.spacebar_vertical_correction); 57 } 58 LatinKeyboard(Context context, int layoutTemplateResId, CharSequence characters, int columns, int horizontalPadding)59 public LatinKeyboard(Context context, int layoutTemplateResId, 60 CharSequence characters, int columns, int horizontalPadding) { 61 super(context, layoutTemplateResId, characters, columns, horizontalPadding); 62 } 63 64 @Override createKeyFromXml(Resources res, Row parent, int x, int y, XmlResourceParser parser)65 protected Key createKeyFromXml(Resources res, Row parent, int x, int y, 66 XmlResourceParser parser) { 67 Key key = new LatinKey(res, parent, x, y, parser); 68 if (key.codes[0] == 10) { 69 mEnterKey = key; 70 } 71 return key; 72 } 73 setImeOptions(Resources res, int mode, int options)74 void setImeOptions(Resources res, int mode, int options) { 75 if (mEnterKey != null) { 76 // Reset some of the rarely used attributes. 77 mEnterKey.popupCharacters = null; 78 mEnterKey.popupResId = 0; 79 mEnterKey.text = null; 80 switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) { 81 case EditorInfo.IME_ACTION_GO: 82 mEnterKey.iconPreview = null; 83 mEnterKey.icon = null; 84 mEnterKey.label = res.getText(R.string.label_go_key); 85 break; 86 case EditorInfo.IME_ACTION_NEXT: 87 mEnterKey.iconPreview = null; 88 mEnterKey.icon = null; 89 mEnterKey.label = res.getText(R.string.label_next_key); 90 break; 91 case EditorInfo.IME_ACTION_DONE: 92 mEnterKey.iconPreview = null; 93 mEnterKey.icon = null; 94 mEnterKey.label = res.getText(R.string.label_done_key); 95 break; 96 case EditorInfo.IME_ACTION_SEARCH: 97 mEnterKey.iconPreview = res.getDrawable( 98 R.drawable.sym_keyboard_feedback_search); 99 mEnterKey.icon = res.getDrawable( 100 R.drawable.sym_keyboard_search); 101 mEnterKey.label = null; 102 break; 103 case EditorInfo.IME_ACTION_SEND: 104 mEnterKey.iconPreview = null; 105 mEnterKey.icon = null; 106 mEnterKey.label = res.getText(R.string.label_send_key); 107 break; 108 default: 109 if (mode == KeyboardSwitcher.MODE_IM) { 110 mEnterKey.icon = null; 111 mEnterKey.iconPreview = null; 112 mEnterKey.label = ":-)"; 113 mEnterKey.text = ":-) "; 114 mEnterKey.popupResId = R.xml.popup_smileys; 115 } else { 116 mEnterKey.iconPreview = res.getDrawable( 117 R.drawable.sym_keyboard_feedback_return); 118 mEnterKey.icon = res.getDrawable( 119 R.drawable.sym_keyboard_return); 120 mEnterKey.label = null; 121 } 122 break; 123 } 124 // Set the initial size of the preview icon 125 if (mEnterKey.iconPreview != null) { 126 mEnterKey.iconPreview.setBounds(0, 0, 127 mEnterKey.iconPreview.getIntrinsicWidth(), 128 mEnterKey.iconPreview.getIntrinsicHeight()); 129 } 130 } 131 } 132 enableShiftLock()133 void enableShiftLock() { 134 int index = getShiftKeyIndex(); 135 if (index >= 0) { 136 mShiftKey = getKeys().get(index); 137 if (mShiftKey instanceof LatinKey) { 138 ((LatinKey)mShiftKey).enableShiftLock(); 139 } 140 mOldShiftIcon = mShiftKey.icon; 141 mOldShiftPreviewIcon = mShiftKey.iconPreview; 142 } 143 } 144 setShiftLocked(boolean shiftLocked)145 void setShiftLocked(boolean shiftLocked) { 146 if (mShiftKey != null) { 147 if (shiftLocked) { 148 mShiftKey.on = true; 149 mShiftKey.icon = mShiftLockIcon; 150 mShiftState = SHIFT_LOCKED; 151 } else { 152 mShiftKey.on = false; 153 mShiftKey.icon = mShiftLockIcon; 154 mShiftState = SHIFT_ON; 155 } 156 } 157 } 158 isShiftLocked()159 boolean isShiftLocked() { 160 return mShiftState == SHIFT_LOCKED; 161 } 162 163 @Override setShifted(boolean shiftState)164 public boolean setShifted(boolean shiftState) { 165 boolean shiftChanged = false; 166 if (mShiftKey != null) { 167 if (shiftState == false) { 168 shiftChanged = mShiftState != SHIFT_OFF; 169 mShiftState = SHIFT_OFF; 170 mShiftKey.on = false; 171 mShiftKey.icon = mOldShiftIcon; 172 } else { 173 if (mShiftState == SHIFT_OFF) { 174 shiftChanged = mShiftState == SHIFT_OFF; 175 mShiftState = SHIFT_ON; 176 mShiftKey.icon = mShiftLockIcon; 177 } 178 } 179 } else { 180 return super.setShifted(shiftState); 181 } 182 return shiftChanged; 183 } 184 185 @Override isShifted()186 public boolean isShifted() { 187 if (mShiftKey != null) { 188 return mShiftState != SHIFT_OFF; 189 } else { 190 return super.isShifted(); 191 } 192 } 193 194 static class LatinKey extends Keyboard.Key { 195 196 private boolean mShiftLockEnabled; 197 LatinKey(Resources res, Keyboard.Row parent, int x, int y, XmlResourceParser parser)198 public LatinKey(Resources res, Keyboard.Row parent, int x, int y, 199 XmlResourceParser parser) { 200 super(res, parent, x, y, parser); 201 if (popupCharacters != null && popupCharacters.length() == 0) { 202 // If there is a keyboard with no keys specified in popupCharacters 203 popupResId = 0; 204 } 205 } 206 enableShiftLock()207 void enableShiftLock() { 208 mShiftLockEnabled = true; 209 } 210 211 @Override onReleased(boolean inside)212 public void onReleased(boolean inside) { 213 if (!mShiftLockEnabled) { 214 super.onReleased(inside); 215 } else { 216 pressed = !pressed; 217 } 218 } 219 220 /** 221 * Overriding this method so that we can reduce the target area for certain keys. 222 */ 223 @Override isInside(int x, int y)224 public boolean isInside(int x, int y) { 225 final int code = codes[0]; 226 if (code == KEYCODE_SHIFT || 227 code == KEYCODE_DELETE) { 228 y -= height / 10; 229 if (code == KEYCODE_SHIFT) x += width / 6; 230 if (code == KEYCODE_DELETE) x -= width / 6; 231 } else if (code == LatinIME.KEYCODE_SPACE) { 232 y += LatinKeyboard.sSpacebarVerticalCorrection; 233 } 234 return super.isInside(x, y); 235 } 236 } 237 } 238