SuddenJumpingTouchEventHandler.java revision 230cd6f7f27300e2688b5e5a22a5361f446b80e7
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/*
2923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Copyright (C) 2008-2009 Google Inc.
3923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of
6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at
7923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
9923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under
14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License.
15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */
16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin;
18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
19923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Context;
20923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.graphics.Canvas;
21923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.inputmethodservice.Keyboard;
22923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.inputmethodservice.KeyboardView;
23923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.inputmethodservice.Keyboard.Key;
24923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Handler;
25923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Message;
26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.SystemClock;
27923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.AttributeSet;
28923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.MotionEvent;
29923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
30923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport java.util.List;
31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
32923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpublic class LatinKeyboardView extends KeyboardView {
33923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
34923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    static final int KEYCODE_OPTIONS = -100;
35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    static final int KEYCODE_SHIFT_LONGPRESS = -101;
36230cd6f7f27300e2688b5e5a22a5361f446b80e7Amith Yamasani
37923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private Keyboard mPhoneKeyboard;
38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public LatinKeyboardView(Context context, AttributeSet attrs) {
40923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        super(context, attrs);
41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) {
44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        super(context, attrs, defStyle);
45923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
46230cd6f7f27300e2688b5e5a22a5361f446b80e7Amith Yamasani
47923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void setPhoneKeyboard(Keyboard phoneKeyboard) {
48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPhoneKeyboard = phoneKeyboard;
49923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
50230cd6f7f27300e2688b5e5a22a5361f446b80e7Amith Yamasani
51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    protected boolean onLongPress(Key key) {
53923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (key.codes[0] == Keyboard.KEYCODE_MODE_CHANGE) {
54923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null);
55923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            return true;
56923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        } else if (key.codes[0] == Keyboard.KEYCODE_SHIFT) {
57923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            getOnKeyboardActionListener().onKey(KEYCODE_SHIFT_LONGPRESS, null);
58230cd6f7f27300e2688b5e5a22a5361f446b80e7Amith Yamasani            invalidateAllKeys();
59923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            return true;
60923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        } else if (key.codes[0] == '0' && getKeyboard() == mPhoneKeyboard) {
61923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            // Long pressing on 0 in phone number keypad gives you a '+'.
62923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            getOnKeyboardActionListener().onKey('+', null);
63923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            return true;
64923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        } else {
65923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            return super.onLongPress(key);
66923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
67923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
68923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
69923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
70923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    /****************************  INSTRUMENTATION  *******************************/
71923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
72923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    static final boolean DEBUG_AUTO_PLAY = false;
73923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int MSG_TOUCH_DOWN = 1;
74923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private static final int MSG_TOUCH_UP = 2;
75923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
76923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    Handler mHandler2;
77923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
78923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private String mStringToPlay;
79923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mStringIndex;
80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private boolean mDownDelivered;
81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private Key[] mAsciiKeys = new Key[256];
82923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private boolean mPlaying;
83923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
84923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
85923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void setKeyboard(Keyboard k) {
86923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        super.setKeyboard(k);
87923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (DEBUG_AUTO_PLAY) {
88923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            findKeys();
89923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mHandler2 == null) {
90923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mHandler2 = new Handler() {
91923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    @Override
92923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    public void handleMessage(Message msg) {
93923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        removeMessages(MSG_TOUCH_DOWN);
94923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        removeMessages(MSG_TOUCH_UP);
95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        if (mPlaying == false) return;
96923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
97923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        switch (msg.what) {
98923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                            case MSG_TOUCH_DOWN:
99923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                if (mStringIndex >= mStringToPlay.length()) {
100923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                    mPlaying = false;
101923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                    return;
102923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                }
103923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                char c = mStringToPlay.charAt(mStringIndex);
104923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                while (c > 255 || mAsciiKeys[(int) c] == null) {
105923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                    mStringIndex++;
106923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                    if (mStringIndex >= mStringToPlay.length()) {
107923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                        mPlaying = false;
108923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                        return;
109923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                    }
110923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                    c = mStringToPlay.charAt(mStringIndex);
111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                }
112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                int x = mAsciiKeys[c].x + 10;
113923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                int y = mAsciiKeys[c].y + 26;
114923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                MotionEvent me = MotionEvent.obtain(SystemClock.uptimeMillis(),
115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                        SystemClock.uptimeMillis(),
116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                        MotionEvent.ACTION_DOWN, x, y, 0);
117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                LatinKeyboardView.this.dispatchTouchEvent(me);
118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                me.recycle();
119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                sendEmptyMessageDelayed(MSG_TOUCH_UP, 500); // Deliver up in 500ms if nothing else
120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                // happens
121923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                mDownDelivered = true;
122923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                break;
123923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                            case MSG_TOUCH_UP:
124923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                char cUp = mStringToPlay.charAt(mStringIndex);
125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                int x2 = mAsciiKeys[cUp].x + 10;
126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                int y2 = mAsciiKeys[cUp].y + 26;
127923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                mStringIndex++;
128923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                MotionEvent me2 = MotionEvent.obtain(SystemClock.uptimeMillis(),
130923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                        SystemClock.uptimeMillis(),
131923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                        MotionEvent.ACTION_UP, x2, y2, 0);
132923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                LatinKeyboardView.this.dispatchTouchEvent(me2);
133923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                me2.recycle();
134923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 500); // Deliver up in 500ms if nothing else
135923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                // happens
136923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                mDownDelivered = false;
137923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                                break;
138923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                        }
139923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                    }
140923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                };
141923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
142923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
143923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private void findKeys() {
147923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        List<Key> keys = getKeyboard().getKeys();
148923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        // Get the keys on this keyboard
149923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        for (int i = 0; i < keys.size(); i++) {
150923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            int code = keys.get(i).codes[0];
151923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (code >= 0 && code <= 255) {
152923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mAsciiKeys[code] = keys.get(i);
153923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
154923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
155923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
156923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
157923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    void startPlaying(String s) {
158923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (!DEBUG_AUTO_PLAY) return;
159923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (s == null) return;
160923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mStringToPlay = s.toLowerCase();
161923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mPlaying = true;
162923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mDownDelivered = false;
163923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mStringIndex = 0;
164923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 10);
165923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
166923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
167923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    @Override
168923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public void draw(Canvas c) {
169923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        super.draw(c);
170923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        if (DEBUG_AUTO_PLAY && mPlaying) {
171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mHandler2.removeMessages(MSG_TOUCH_DOWN);
172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            mHandler2.removeMessages(MSG_TOUCH_UP);
173923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            if (mDownDelivered) {
174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_UP, 20);
175923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            } else {
176923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project                mHandler2.sendEmptyMessageDelayed(MSG_TOUCH_DOWN, 20);
177923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            }
178923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
179923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
180923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project}
181