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.graphics.Canvas; 21 import android.inputmethodservice.Keyboard; 22 import android.inputmethodservice.KeyboardView; 23 import android.inputmethodservice.Keyboard.Key; 24 import android.os.Handler; 25 import android.os.Message; 26 import android.os.SystemClock; 27 import android.util.AttributeSet; 28 import android.view.MotionEvent; 29 30 import java.util.List; 31 32 public class LatinKeyboardView extends KeyboardView { 33 34 static final int KEYCODE_OPTIONS = -100; 35 static final int KEYCODE_SHIFT_LONGPRESS = -101; 36 37 private Keyboard mPhoneKeyboard; 38 LatinKeyboardView(Context context, AttributeSet attrs)39 public LatinKeyboardView(Context context, AttributeSet attrs) { 40 super(context, attrs); 41 } 42 LatinKeyboardView(Context context, AttributeSet attrs, int defStyle)43 public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) { 44 super(context, attrs, defStyle); 45 } 46 setPhoneKeyboard(Keyboard phoneKeyboard)47 public void setPhoneKeyboard(Keyboard phoneKeyboard) { 48 mPhoneKeyboard = phoneKeyboard; 49 } 50 51 @Override onLongPress(Key key)52 protected boolean onLongPress(Key key) { 53 if (key.codes[0] == Keyboard.KEYCODE_MODE_CHANGE) { 54 getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null); 55 return true; 56 } else if (key.codes[0] == Keyboard.KEYCODE_SHIFT) { 57 getOnKeyboardActionListener().onKey(KEYCODE_SHIFT_LONGPRESS, null); 58 invalidateAllKeys(); 59 return true; 60 } else if (key.codes[0] == '0' && getKeyboard() == mPhoneKeyboard) { 61 // Long pressing on 0 in phone number keypad gives you a '+'. 62 getOnKeyboardActionListener().onKey('+', null); 63 return true; 64 } else { 65 return super.onLongPress(key); 66 } 67 } 68 69 70 /**************************** INSTRUMENTATION *******************************/ 71 72 static final boolean DEBUG_AUTO_PLAY = false; 73 private static final int MSG_TOUCH_DOWN = 1; 74 private static final int MSG_TOUCH_UP = 2; 75 76 Handler mHandler2; 77 78 private String mStringToPlay; 79 private int mStringIndex; 80 private boolean mDownDelivered; 81 private Key[] mAsciiKeys = new Key[256]; 82 private boolean mPlaying; 83 84 @Override setKeyboard(Keyboard k)85 public void setKeyboard(Keyboard k) { 86 super.setKeyboard(k); 87 if (DEBUG_AUTO_PLAY) { 88 findKeys(); 89 if (mHandler2 == null) { 90 mHandler2 = new Handler() { 91 @Override 92 public void handleMessage(Message msg) { 93 removeMessages(MSG_TOUCH_DOWN); 94 removeMessages(MSG_TOUCH_UP); 95 if (mPlaying == false) return; 96 97 switch (msg.what) { 98 case MSG_TOUCH_DOWN: 99 if (mStringIndex >= mStringToPlay.length()) { 100 mPlaying = false; 101 return; 102 } 103 char c = mStringToPlay.charAt(mStringIndex); 104 while (c > 255 || mAsciiKeys[(int) c] == null) { 105 mStringIndex++; 106 if (mStringIndex >= mStringToPlay.length()) { 107 mPlaying = false; 108 return; 109 } 110 c = mStringToPlay.charAt(mStringIndex); 111 } 112 int x = mAsciiKeys[c].x + 10; 113 int y = mAsciiKeys[c].y + 26; 114 MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(), 115 SystemClock.uptimeMillis(), 116 MotionEvent.ACTION_DOWN, x, y, 0); 117 LatinKeyboardView.this.dispatchTouchEvent(me); 118 me.recycle(); 119 sendEmptyMessageDelayed(MSG_TOUCH_UP, 500); // Deliver up in 500ms if nothing else 120 // happens 121 mDownDelivered = true; 122 break; 123 case MSG_TOUCH_UP: 124 char cUp = mStringToPlay.charAt(mStringIndex); 125 int x2 = mAsciiKeys[cUp].x + 10; 126 int y2 = mAsciiKeys[cUp].y + 26; 127 mStringIndex++; 128 129 MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(), 130 SystemClock.uptimeMillis(), 131 MotionEvent.ACTION_UP, x2, y2, 0); 132 LatinKeyboardView.this.dispatchTouchEvent(me2); 133 me2.recycle(); 134 sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 500); // Deliver up in 500ms if nothing else 135 // happens 136 mDownDelivered = false; 137 break; 138 } 139 } 140 }; 141 142 } 143 } 144 } 145 findKeys()146 private void findKeys() { 147 List<Key> keys = getKeyboard().getKeys(); 148 // Get the keys on this keyboard 149 for (int i = 0; i < keys.size(); i++) { 150 int code = keys.get(i).codes[0]; 151 if (code >= 0 && code <= 255) { 152 mAsciiKeys[code] = keys.get(i); 153 } 154 } 155 } 156 startPlaying(String s)157 void startPlaying(String s) { 158 if (!DEBUG_AUTO_PLAY) return; 159 if (s == null) return; 160 mStringToPlay = s.toLowerCase(); 161 mPlaying = true; 162 mDownDelivered = false; 163 mStringIndex = 0; 164 mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 10); 165 } 166 167 @Override draw(Canvas c)168 public void draw(Canvas c) { 169 super.draw(c); 170 if (DEBUG_AUTO_PLAY && mPlaying) { 171 mHandler2.removeMessages(MSG_TOUCH_DOWN); 172 mHandler2.removeMessages(MSG_TOUCH_UP); 173 if (mDownDelivered) { 174 mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_UP, 20); 175 } else { 176 mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 20); 177 } 178 } 179 } 180 } 181