speech_input_bubble.h revision bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SPEECH_SPEECH_INPUT_BUBBLE_H_
6#define CHROME_BROWSER_SPEECH_SPEECH_INPUT_BUBBLE_H_
7#pragma once
8
9#include <vector>
10
11#include "base/scoped_ptr.h"
12#include "base/string16.h"
13#include "base/task.h"
14
15namespace gfx {
16class Rect;
17}
18class SkBitmap;
19class TabContents;
20
21// SpeechInputBubble displays a popup info bubble during speech recognition,
22// points to the html element which requested speech input and shows recognition
23// progress events. The popup is closed by the user clicking anywhere outside
24// the popup window, or by the caller destroying this object.
25class SpeechInputBubble {
26 public:
27  // The various buttons which may be part of the bubble.
28  enum Button {
29    BUTTON_TRY_AGAIN,
30    BUTTON_CANCEL
31  };
32
33  // Informs listeners of user actions in the bubble.
34  class Delegate {
35   public:
36    // Invoked when the user selects a button in the info bubble. The InfoBubble
37    // is still active and the caller should close it if necessary.
38    virtual void InfoBubbleButtonClicked(Button button) = 0;
39
40    // Invoked when the user clicks outside the InfoBubble causing it to close.
41    // The InfoBubble window is no longer visible on screen and the caller can
42    // free the InfoBubble instance. This callback is not issued if the bubble
43    // got closed because the object was destroyed by the caller.
44    virtual void InfoBubbleFocusChanged() = 0;
45
46   protected:
47    virtual ~Delegate() {
48    }
49  };
50
51  // Factory method to create new instances.
52  // Creates the bubble, call |Show| to display it on screen.
53  // |tab_contents| is the TabContents hosting the page.
54  // |element_rect| is the display bounds of the html element requesting speech
55  // input (in page coordinates).
56  static SpeechInputBubble* Create(TabContents* tab_contents,
57                                   Delegate* delegate,
58                                   const gfx::Rect& element_rect);
59
60  // This is implemented by platform specific code to create the underlying
61  // bubble window. Not to be called directly by users of this class.
62  static SpeechInputBubble* CreateNativeBubble(TabContents* tab_contents,
63                                               Delegate* delegate,
64                                               const gfx::Rect& element_rect);
65
66  // |Create| uses the currently registered FactoryMethod to create the
67  // SpeechInputBubble instances. FactoryMethod is intended for testing.
68  typedef SpeechInputBubble* (*FactoryMethod)(TabContents*,
69                                              Delegate*,
70                                              const gfx::Rect&);
71  // Sets the factory used by the static method Create. SpeechInputBubble does
72  // not take ownership of |factory|. A value of NULL results in a
73  // SpeechInputBubble being created directly.
74#if defined(UNIT_TEST)
75  static void set_factory(FactoryMethod factory) { factory_ = factory; }
76#endif
77
78  virtual ~SpeechInputBubble() {}
79
80  // Indicates to the user that audio recording is in progress. If the bubble is
81  // hidden, |Show| must be called to make it appear on screen.
82  virtual void SetRecordingMode() = 0;
83
84  // Indicates to the user that recognition is in progress. If the bubble is
85  // hidden, |Show| must be called to make it appear on screen.
86  virtual void SetRecognizingMode() = 0;
87
88  // Displays the given string with the 'Try again' and 'Cancel' buttons. If the
89  // bubble is hidden, |Show| must be called to make it appear on screen.
90  virtual void SetMessage(const string16& text) = 0;
91
92  // Brings up the bubble on screen.
93  virtual void Show() = 0;
94
95  // Hides the info bubble, resulting in a call to
96  // |Delegate::InfoBubbleFocusChanged| as well.
97  virtual void Hide() = 0;
98
99  // Updates the current captured audio volume displayed on screen.
100  virtual void SetInputVolume(float volume) = 0;
101
102  // The horizontal distance between the start of the html widget and the speech
103  // bubble's arrow.
104  static const int kBubbleTargetOffsetX;
105
106 private:
107  static FactoryMethod factory_;
108};
109
110// Base class for the platform specific bubble implementations, this contains
111// the platform independent code for SpeechInputBubble.
112class SpeechInputBubbleBase : public SpeechInputBubble {
113 public:
114  // The current display mode of the bubble, useful only for the platform
115  // specific implementation.
116  enum DisplayMode {
117    DISPLAY_MODE_RECORDING,
118    DISPLAY_MODE_RECOGNIZING,
119    DISPLAY_MODE_MESSAGE
120  };
121
122  SpeechInputBubbleBase();
123  virtual ~SpeechInputBubbleBase();
124
125  // SpeechInputBubble methods
126  virtual void SetRecordingMode();
127  virtual void SetRecognizingMode();
128  virtual void SetMessage(const string16& text);
129  virtual void SetInputVolume(float volume);
130
131 protected:
132  // Updates the platform specific UI layout for the current display mode.
133  virtual void UpdateLayout() = 0;
134
135  // Sets the given image as the image to display in the speech bubble.
136  // TODO(satish): Make the SetRecognizingMode call use this to show an
137  // animation while waiting for results.
138  virtual void SetImage(const SkBitmap& image) = 0;
139
140  DisplayMode display_mode() {
141    return display_mode_;
142  }
143
144  string16 message_text() {
145    return message_text_;
146  }
147
148 private:
149  void DoRecognizingAnimationStep();
150
151  // Task factory used for animation timer.
152  ScopedRunnableMethodFactory<SpeechInputBubbleBase> task_factory_;
153  int animation_step_;  // Current index/step of the animation.
154  std::vector<SkBitmap> animation_frames_;
155
156  DisplayMode display_mode_;
157  string16 message_text_;  // Text displayed in DISPLAY_MODE_MESSAGE
158  // The current microphone image with volume level indication.
159  scoped_ptr<SkBitmap> mic_image_;
160  // A temporary buffer image used in creating the above mic image.
161  scoped_ptr<SkBitmap> buffer_image_;
162
163  static SkBitmap* mic_full_;  // Mic image with full volume.
164  static SkBitmap* mic_empty_;  // Mic image with zero volume.
165  static SkBitmap* mic_mask_;  // Gradient mask used by the volume indicator.
166  static SkBitmap* spinner_;  // Spinner image for the progress animation.
167  static const int kRecognizingAnimationStepMs;
168};
169
170// This typedef is to workaround the issue with certain versions of
171// Visual Studio where it gets confused between multiple Delegate
172// classes and gives a C2500 error. (I saw this error on the try bots -
173// the workaround was not needed for my machine).
174typedef SpeechInputBubble::Delegate SpeechInputBubbleDelegate;
175
176#endif  // CHROME_BROWSER_SPEECH_SPEECH_INPUT_BUBBLE_H_
177