PageRenderTime 23ms CodeModel.GetById 1ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/tutorial/LatinIMETutorial.java

http://eyes-free.googlecode.com/
Java | 326 lines | 209 code | 65 blank | 52 comment | 34 complexity | 939d55c8ece2c7f9f0b937f21a55cda7 MD5 | raw file
  1/*
  2 * Copyright (C) 2011 Google Inc.
  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
 17package com.googlecode.eyesfree.inputmethod.latin.tutorial;
 18
 19import android.app.Activity;
 20import android.content.BroadcastReceiver;
 21import android.content.Context;
 22import android.content.Intent;
 23import android.content.IntentFilter;
 24import android.os.Bundle;
 25import android.util.Log;
 26import android.view.KeyEvent;
 27import android.view.View;
 28import android.widget.ViewAnimator;
 29
 30import com.googlecode.eyesfree.inputmethod.latin.LatinIME;
 31import com.googlecode.eyesfree.inputmethod.latin.R;
 32
 33/**
 34 * This class provides a short tutorial that introduces the user to the features
 35 * available in the accessible Latin IME.
 36 *
 37 * @author alanv@google.com (Alan Viverette)
 38 */
 39public class LatinIMETutorial extends Activity
 40        implements TutorialController, View.OnClickListener, TutorialReader.ReaderListener {
 41    /** Intent action for launching this activity. */
 42    public static final String ACTION =
 43            "com.googlecode.eyesfree.inputmethod.latin.tutorial.LAUNCH_TUTORIAL";
 44
 45    /** Instance state saving constant for the active module. */
 46    private static final String KEY_ACTIVE_MODULE = "active_module";
 47
 48    /** The index of the module to show when first opening the tutorial. */
 49    private static final int DEFAULT_MODULE = 0;
 50
 51    /** Broadcast receiver for high-level keyboard events. */
 52    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
 53        @Override
 54        public void onReceive(Context context, Intent intent) {
 55            String action = intent.getAction();
 56            int mode = intent.getIntExtra(LatinIME.EXTRA_MODE, -1);
 57
 58            LatinTutorialLogger.log(Log.INFO, "Received broadcast with action %s", action);
 59
 60            if (LatinIME.BROADCAST_KEYBOARD_MODE_CHANGE.equals(action)) {
 61                onKeyboardModeChanged(mode);
 62            } else if (LatinIME.BROADCAST_KEYBOARD_MODE_UPDATE.equals(action)) {
 63                onKeyboardModeUpdated(mode);
 64            } else {
 65                onKeyboardBroadcast(action, intent.getExtras());
 66            }
 67        }
 68    };
 69
 70    /** View animator for switching between modules. */
 71    private ViewAnimator mViewAnimator;
 72
 73    /** The currently focused tutorial module. */
 74    private TutorialModule mActiveModule;
 75
 76    /** The TTS queue for this tutorial. */
 77    private TutorialReader mReader;
 78
 79    /** The current keyboard mode, or -1 if no keyboard active. */
 80    private int mKeyboardMode;
 81
 82    @Override
 83    protected void onCreate(Bundle savedInstanceState) {
 84        super.onCreate(savedInstanceState);
 85
 86        setTitle("");
 87        setContentView(R.layout.tutorial_0_switcher);
 88
 89        mReader = new TutorialReader(this);
 90        mReader.setListener(this);
 91
 92        mViewAnimator = (ViewAnimator) findViewById(R.id.tutorial_switcher);
 93        mViewAnimator.addView(new LatinTutorialModule1(this, this));
 94        mViewAnimator.addView(new LatinTutorialModule2(this, this));
 95        mViewAnimator.addView(new LatinTutorialModule3(this, this));
 96        mViewAnimator.addView(new LatinTutorialModule4(this, this));
 97
 98        mKeyboardMode = -1;
 99
100        IntentFilter intentFilter = new IntentFilter();
101        intentFilter.addAction(LatinIME.BROADCAST_KEYBOARD_MODE_CHANGE);
102        intentFilter.addAction(LatinIME.BROADCAST_KEYBOARD_MODE_UPDATE);
103        intentFilter.addAction(LatinIME.BROADCAST_LEFT_KEYBOARD_AREA);
104        intentFilter.addAction(LatinIME.BROADCAST_ENTERED_KEYBOARD_AREA);
105        intentFilter.addAction(LatinIME.BROADCAST_UP_OUTSIDE_KEYBOARD);
106        intentFilter.addAction(LatinIME.BROADCAST_GRANULARITY_CHANGE);
107
108        registerReceiver(mReceiver, intentFilter);
109
110        requestKeyboardModeUpdate();
111
112        if (savedInstanceState != null) {
113            show(savedInstanceState.getInt(KEY_ACTIVE_MODULE, DEFAULT_MODULE));
114        } else {
115            show(DEFAULT_MODULE);
116        }
117    }
118
119    @Override
120    protected void onSaveInstanceState(Bundle outState) {
121        super.onSaveInstanceState(outState);
122
123        outState.putInt(KEY_ACTIVE_MODULE, mViewAnimator.getDisplayedChild());
124    }
125
126    @Override
127    protected void onPause() {
128        super.onPause();
129
130        mReader.clear();
131    }
132
133    @Override
134    protected void onDestroy() {
135        super.onDestroy();
136
137        unregisterReceiver(mReceiver);
138
139        mReader.release();
140    }
141
142    @Override
143    public void startActivityForResult(Intent intent, int requestCode) {
144        mReader.clear();
145
146        super.startActivityForResult(intent, requestCode);
147    }
148
149    @Override
150    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
151        super.onActivityResult(requestCode, resultCode, data);
152
153        if (mActiveModule != null && mActiveModule instanceof ActivityResultListener) {
154            ((ActivityResultListener) mActiveModule).onActivityResult(
155                    requestCode, resultCode, data);
156        }
157    }
158
159    @Override
160    public boolean dispatchKeyEvent(KeyEvent event) {
161        boolean handled = false;
162
163        if (mActiveModule != null && mActiveModule instanceof View.OnKeyListener) {
164            handled = ((View.OnKeyListener) mActiveModule).onKey(null, event.getKeyCode(), event);
165        }
166
167        if (!handled) {
168            handled = super.dispatchKeyEvent(event);
169        }
170
171        return handled;
172    }
173
174    @Override
175    public void onClick(View v) {
176        if (v.getId() == R.id.tutorial_instructions) {
177            mReader.next();
178            return;
179        }
180
181        if (mActiveModule != null && mActiveModule instanceof View.OnClickListener) {
182            ((View.OnClickListener) mActiveModule).onClick(v);
183        }
184    }
185
186    @Override
187    public void onUtteranceCompleted(int utteranceId) {
188        if (mActiveModule != null) {
189            mActiveModule.onUtteranceCompleted(utteranceId);
190        }
191    }
192
193    /**
194     * Updates the internal representation of the keyboard mode and notifies
195     * children.
196     *
197     * @param mode The current keyboard mode.
198     * @see
199     *      com.googlecode.eyesfree.inputmethod.latin.KeyboardSwitcher#getKeyboardMode()
200     */
201    protected void onKeyboardModeChanged(int mode) {
202        LatinTutorialLogger.log(Log.INFO, "Keyboard mode changed to %d", mode);
203
204        mKeyboardMode = mode;
205
206        if (mActiveModule != null && mActiveModule instanceof KeyboardModeListener) {
207            ((KeyboardModeListener) mActiveModule).onKeyboardModeChanged(mode);
208        }
209    }
210
211    /**
212     * Forwards keyboard event broadcasts to the active module, if the module
213     * implements {@link KeyboardBroadcastListener}.
214     *
215     * @param action The broadcast's action.
216     * @param extras The broadcast's extras bundle.
217     */
218    protected void onKeyboardBroadcast(String action, Bundle extras) {
219        if (mActiveModule != null && mActiveModule instanceof KeyboardBroadcastListener) {
220            ((KeyboardBroadcastListener) mActiveModule).onKeyboardBroadcast(action, extras);
221        }
222    }
223
224    /**
225     * Updates the internal representation of the keyboard mode, but does not
226     * notify children because the mode has not changed.
227     *
228     * @param mode The current keyboard mode.
229     * @see
230     *      com.googlecode.eyesfree.inputmethod.latin.KeyboardSwitcher#getKeyboardMode()
231     */
232    protected void onKeyboardModeUpdated(int mode) {
233        mKeyboardMode = mode;
234
235        if (mActiveModule != null && mActiveModule instanceof KeyboardModeListener) {
236            ((KeyboardModeListener) mActiveModule).onKeyboardModeUpdated(mode);
237        }
238    }
239
240    @Override
241    public int getKeyboardMode() {
242        return mKeyboardMode;
243    }
244
245    @Override
246    public void requestKeyboardModeUpdate() {
247        sendBroadcast(new Intent(LatinIME.REQUEST_KEYBOARD_MODE_UPDATE));
248    }
249
250    @Override
251    public void setKeyboardMode(int mode) {
252        Intent modeRequest = new Intent(LatinIME.REQUEST_KEYBOARD_MODE_CHANGE);
253        modeRequest.putExtra(LatinIME.EXTRA_MODE, mode);
254        sendBroadcast(modeRequest);
255    }
256
257    @Override
258    public void speak(String text, int utteranceId) {
259        mReader.queue(text, utteranceId);
260    }
261
262    @Override
263    public void show(int which) {
264        if (which < 0 || which >= mViewAnimator.getChildCount()) {
265            LatinTutorialLogger.log(Log.ERROR, "Attempted to show invalid child index %d", which);
266            return;
267        }
268
269        mReader.clear();
270
271        int displayedIndex = mViewAnimator.getDisplayedChild();
272        View displayedView = mViewAnimator.getChildAt(displayedIndex);
273
274        if (displayedView instanceof TutorialModule) {
275            deactivateModule((TutorialModule) displayedView);
276        }
277
278        mViewAnimator.setDisplayedChild(which);
279        View viewToDisplay = mViewAnimator.getChildAt(which);
280
281        if (viewToDisplay instanceof TutorialModule) {
282            activateModule((TutorialModule) viewToDisplay);
283        }
284    }
285
286    private void deactivateModule(TutorialModule module) {
287        mReader.clear();
288        mActiveModule = null;
289        mViewAnimator.setOnKeyListener(null);
290        module.onHidden();
291    }
292
293    private void activateModule(TutorialModule module) {
294        mActiveModule = module;
295        module.onShown();
296    }
297
298    @Override
299    public void next() {
300        show(mViewAnimator.getDisplayedChild() + 1);
301    }
302
303    @Override
304    public void skip(int index) {
305        show(mViewAnimator.getDisplayedChild() + 1 + index);
306    }
307
308    @Override
309    public void previous() {
310        show(mViewAnimator.getDisplayedChild() - 1);
311    }
312
313    static interface ActivityResultListener {
314        public void onActivityResult(int requestCode, int resultCode, Intent data);
315    }
316
317    static interface KeyboardModeListener {
318        public void onKeyboardModeChanged(int mode);
319
320        public void onKeyboardModeUpdated(int mode);
321    }
322
323    static interface KeyboardBroadcastListener {
324        public void onKeyboardBroadcast(String action, Bundle extras);
325    }
326}