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