blob: 7483e7584b87abbf7f433f657203f41734f16c0b [file] [log] [blame]
Jim Miller0b319702010-02-05 18:51:59 -08001/*
2 * Copyright (C) 2010 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
17package com.android.internal.widget;
18
Jim Miller0b319702010-02-05 18:51:59 -080019import android.content.Context;
20import android.content.res.Resources;
21import android.content.res.XmlResourceParser;
Jim Miller0b319702010-02-05 18:51:59 -080022import android.graphics.drawable.Drawable;
23import android.inputmethodservice.Keyboard;
24import android.inputmethodservice.KeyboardView;
Jim Miller0b319702010-02-05 18:51:59 -080025import com.android.internal.R;
26
27/**
28 * A basic, embed-able keyboard designed for password entry. Allows entry of all Latin-1 characters.
29 *
30 * It has two modes: alpha and numeric. In alpha mode, it allows all Latin-1 characters and enables
31 * an additional keyboard with symbols. In numeric mode, it shows a 12-key DTMF dialer-like
32 * keypad with alpha characters hints.
33 */
34public class PasswordEntryKeyboard extends Keyboard {
Jim Miller0b319702010-02-05 18:51:59 -080035 private static final int SHIFT_OFF = 0;
36 private static final int SHIFT_ON = 1;
37 private static final int SHIFT_LOCKED = 2;
38 public static final int KEYCODE_SPACE = ' ';
39
40 private Drawable mShiftIcon;
41 private Drawable mShiftLockIcon;
Jim Miller6465f772011-01-19 22:01:25 -080042
43 // These two arrays must be the same length
44 private Drawable[] mOldShiftIcons = { null, null };
45 private Key[] mShiftKeys = { null, null };
46
Jim Miller0b319702010-02-05 18:51:59 -080047 private Key mEnterKey;
48 private Key mF1Key;
49 private Key mSpaceKey;
Jim Miller0b319702010-02-05 18:51:59 -080050 private int mShiftState = SHIFT_OFF;
51
52 static int sSpacebarVerticalCorrection;
53
54 public PasswordEntryKeyboard(Context context, int xmlLayoutResId) {
55 this(context, xmlLayoutResId, 0);
56 }
57
Jae Yong Sung8171b512010-08-05 10:44:27 -070058 public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int width, int height) {
59 this(context, xmlLayoutResId, 0, width, height);
60 }
61
Jim Miller0b319702010-02-05 18:51:59 -080062 public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int mode) {
63 super(context, xmlLayoutResId, mode);
Jae Yong Sung8171b512010-08-05 10:44:27 -070064 init(context);
65 }
66
67 public PasswordEntryKeyboard(Context context, int xmlLayoutResId, int mode,
68 int width, int height) {
69 super(context, xmlLayoutResId, mode, width, height);
70 init(context);
71 }
72
73 private void init(Context context) {
Jim Miller0b319702010-02-05 18:51:59 -080074 final Resources res = context.getResources();
Alan Viverette8eea3ea2014-02-03 18:40:20 -080075 mShiftIcon = context.getDrawable(R.drawable.sym_keyboard_shift);
76 mShiftLockIcon = context.getDrawable(R.drawable.sym_keyboard_shift_locked);
Jim Miller0b319702010-02-05 18:51:59 -080077 sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
78 R.dimen.password_keyboard_spacebar_vertical_correction);
79 }
80
81 public PasswordEntryKeyboard(Context context, int layoutTemplateResId,
82 CharSequence characters, int columns, int horizontalPadding) {
83 super(context, layoutTemplateResId, characters, columns, horizontalPadding);
84 }
85
86 @Override
87 protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
88 XmlResourceParser parser) {
89 LatinKey key = new LatinKey(res, parent, x, y, parser);
90 final int code = key.codes[0];
91 if (code >=0 && code != '\n' && (code < 32 || code > 127)) {
Jim Millerec52eed2010-02-11 17:27:22 -080092 // Log.w(TAG, "Key code for " + key.label + " is not latin-1");
Jim Miller0b319702010-02-05 18:51:59 -080093 key.label = " ";
94 key.setEnabled(false);
95 }
96 switch (key.codes[0]) {
97 case 10:
98 mEnterKey = key;
99 break;
100 case PasswordEntryKeyboardView.KEYCODE_F1:
101 mF1Key = key;
102 break;
103 case 32:
104 mSpaceKey = key;
105 break;
106 }
107 return key;
108 }
109
110 /**
111 * Allows enter key resources to be overridden
112 * @param res resources to grab given items from
113 * @param previewId preview drawable shown on enter key
114 * @param iconId normal drawable shown on enter key
115 * @param labelId string shown on enter key
116 */
117 void setEnterKeyResources(Resources res, int previewId, int iconId, int labelId) {
118 if (mEnterKey != null) {
119 // Reset some of the rarely used attributes.
120 mEnterKey.popupCharacters = null;
121 mEnterKey.popupResId = 0;
122 mEnterKey.text = null;
123
124 mEnterKey.iconPreview = res.getDrawable(previewId);
125 mEnterKey.icon = res.getDrawable(iconId);
126 mEnterKey.label = res.getText(labelId);
127
128 // Set the initial size of the preview icon
129 if (mEnterKey.iconPreview != null) {
130 mEnterKey.iconPreview.setBounds(0, 0,
131 mEnterKey.iconPreview.getIntrinsicWidth(),
132 mEnterKey.iconPreview.getIntrinsicHeight());
133 }
134 }
135 }
136
137 /**
138 * Allows shiftlock to be turned on. See {@link #setShiftLocked(boolean)}
139 *
140 */
141 void enableShiftLock() {
Jim Miller6465f772011-01-19 22:01:25 -0800142 int i = 0;
143 for (int index : getShiftKeyIndices()) {
144 if (index >= 0 && i < mShiftKeys.length) {
145 mShiftKeys[i] = getKeys().get(index);
146 if (mShiftKeys[i] instanceof LatinKey) {
147 ((LatinKey)mShiftKeys[i]).enableShiftLock();
148 }
149 mOldShiftIcons[i] = mShiftKeys[i].icon;
150 i++;
Jim Miller0b319702010-02-05 18:51:59 -0800151 }
Jim Miller0b319702010-02-05 18:51:59 -0800152 }
153 }
154
155 /**
156 * Turn on shift lock. This turns on the LED for this key, if it has one.
157 * It should be followed by a call to {@link KeyboardView#invalidateKey(int)}
158 * or {@link KeyboardView#invalidateAllKeys()}
159 *
160 * @param shiftLocked
161 */
162 void setShiftLocked(boolean shiftLocked) {
Jim Miller6465f772011-01-19 22:01:25 -0800163 for (Key shiftKey : mShiftKeys) {
164 if (shiftKey != null) {
165 shiftKey.on = shiftLocked;
166 shiftKey.icon = mShiftLockIcon;
Jim Miller0b319702010-02-05 18:51:59 -0800167 }
168 }
Jim Miller6465f772011-01-19 22:01:25 -0800169 mShiftState = shiftLocked ? SHIFT_LOCKED : SHIFT_ON;
Jim Miller0b319702010-02-05 18:51:59 -0800170 }
171
172 /**
173 * Turn on shift mode. Sets shift mode and turns on icon for shift key.
174 * It should be followed by a call to {@link KeyboardView#invalidateKey(int)}
175 * or {@link KeyboardView#invalidateAllKeys()}
176 *
177 * @param shiftLocked
178 */
179 @Override
180 public boolean setShifted(boolean shiftState) {
181 boolean shiftChanged = false;
Jim Miller6465f772011-01-19 22:01:25 -0800182 if (shiftState == false) {
183 shiftChanged = mShiftState != SHIFT_OFF;
184 mShiftState = SHIFT_OFF;
185 } else if (mShiftState == SHIFT_OFF) {
186 shiftChanged = mShiftState == SHIFT_OFF;
187 mShiftState = SHIFT_ON;
188 }
189 for (int i = 0; i < mShiftKeys.length; i++) {
190 if (mShiftKeys[i] != null) {
191 if (shiftState == false) {
192 mShiftKeys[i].on = false;
193 mShiftKeys[i].icon = mOldShiftIcons[i];
194 } else if (mShiftState == SHIFT_OFF) {
195 mShiftKeys[i].on = false;
196 mShiftKeys[i].icon = mShiftIcon;
197 }
198 } else {
199 // return super.setShifted(shiftState);
Jim Miller0b319702010-02-05 18:51:59 -0800200 }
Jim Miller0b319702010-02-05 18:51:59 -0800201 }
202 return shiftChanged;
203 }
204
205 /**
206 * Whether or not keyboard is shifted.
207 * @return true if keyboard state is shifted.
208 */
209 @Override
210 public boolean isShifted() {
Jim Miller6465f772011-01-19 22:01:25 -0800211 if (mShiftKeys[0] != null) {
Jim Miller0b319702010-02-05 18:51:59 -0800212 return mShiftState != SHIFT_OFF;
213 } else {
214 return super.isShifted();
215 }
216 }
217
Jim Miller0b319702010-02-05 18:51:59 -0800218 static class LatinKey extends Keyboard.Key {
219 private boolean mShiftLockEnabled;
220 private boolean mEnabled = true;
221
222 public LatinKey(Resources res, Keyboard.Row parent, int x, int y,
223 XmlResourceParser parser) {
224 super(res, parent, x, y, parser);
225 if (popupCharacters != null && popupCharacters.length() == 0) {
226 // If there is a keyboard with no keys specified in popupCharacters
227 popupResId = 0;
228 }
229 }
230
231 void setEnabled(boolean enabled) {
232 mEnabled = enabled;
233 }
234
235 void enableShiftLock() {
236 mShiftLockEnabled = true;
237 }
238
239 @Override
240 public void onReleased(boolean inside) {
241 if (!mShiftLockEnabled) {
242 super.onReleased(inside);
243 } else {
244 pressed = !pressed;
245 }
246 }
247
248 /**
249 * Overriding this method so that we can reduce the target area for certain keys.
250 */
251 @Override
252 public boolean isInside(int x, int y) {
253 if (!mEnabled) {
254 return false;
255 }
256 final int code = codes[0];
257 if (code == KEYCODE_SHIFT || code == KEYCODE_DELETE) {
258 y -= height / 10;
259 if (code == KEYCODE_SHIFT) x += width / 6;
260 if (code == KEYCODE_DELETE) x -= width / 6;
261 } else if (code == KEYCODE_SPACE) {
262 y += PasswordEntryKeyboard.sSpacebarVerticalCorrection;
263 }
264 return super.isInside(x, y);
265 }
266 }
267}