speech_input_bubble.h revision 3f50c38dc070f4bb515c1b64450dae14f316474e
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  // Returns the TabContents for which this bubble gets displayed.
103  virtual TabContents* tab_contents() = 0;
104
105  // The horizontal distance between the start of the html widget and the speech
106  // bubble's arrow.
107  static const int kBubbleTargetOffsetX;
108
109 private:
110  static FactoryMethod factory_;
111};
112
113// Base class for the platform specific bubble implementations, this contains
114// the platform independent code for SpeechInputBubble.
115class SpeechInputBubbleBase : public SpeechInputBubble {
116 public:
117  // The current display mode of the bubble, useful only for the platform
118  // specific implementation.
119  enum DisplayMode {
120    DISPLAY_MODE_RECORDING,
121    DISPLAY_MODE_RECOGNIZING,
122    DISPLAY_MODE_MESSAGE
123  };
124
125  explicit SpeechInputBubbleBase(TabContents* tab_contents);
126  virtual ~SpeechInputBubbleBase();
127
128  // SpeechInputBubble methods
129  virtual void SetRecordingMode();
130  virtual void SetRecognizingMode();
131  virtual void SetMessage(const string16& text);
132  virtual void SetInputVolume(float volume);
133  virtual TabContents* tab_contents() { return tab_contents_; }
134
135 protected:
136  // Updates the platform specific UI layout for the current display mode.
137  virtual void UpdateLayout() = 0;
138
139  // Sets the given image as the image to display in the speech bubble.
140  // TODO(satish): Make the SetRecognizingMode call use this to show an
141  // animation while waiting for results.
142  virtual void SetImage(const SkBitmap& image) = 0;
143
144  DisplayMode display_mode() {
145    return display_mode_;
146  }
147
148  string16 message_text() {
149    return message_text_;
150  }
151
152 private:
153  void DoRecognizingAnimationStep();
154
155  // Task factory used for animation timer.
156  ScopedRunnableMethodFactory<SpeechInputBubbleBase> task_factory_;
157  int animation_step_;  // Current index/step of the animation.
158  std::vector<SkBitmap> animation_frames_;
159
160  DisplayMode display_mode_;
161  string16 message_text_;  // Text displayed in DISPLAY_MODE_MESSAGE
162  // The current microphone image with volume level indication.
163  scoped_ptr<SkBitmap> mic_image_;
164  // A temporary buffer image used in creating the above mic image.
165  scoped_ptr<SkBitmap> buffer_image_;
166  // TabContents in which this this bubble gets displayed.
167  TabContents* tab_contents_;
168
169  static SkBitmap* mic_full_;  // Mic image with full volume.
170  static SkBitmap* mic_empty_;  // Mic image with zero volume.
171  static SkBitmap* mic_mask_;  // Gradient mask used by the volume indicator.
172  static SkBitmap* spinner_;  // Spinner image for the progress animation.
173  static const int kRecognizingAnimationStepMs;
174};
175
176// This typedef is to workaround the issue with certain versions of
177// Visual Studio where it gets confused between multiple Delegate
178// classes and gives a C2500 error. (I saw this error on the try bots -
179// the workaround was not needed for my machine).
180typedef SpeechInputBubble::Delegate SpeechInputBubbleDelegate;
181
182#endif  // CHROME_BROWSER_SPEECH_SPEECH_INPUT_BUBBLE_H_
183