Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(364)

Side by Side Diff: chrome/browser/views/speech_input_bubble.cc

Issue 3133034: Adds a speech input info bubble. (Closed)
Patch Set: Reorganised speech bubble into an interface and implementation. Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "chrome/browser/speech/speech_input_bubble.h"
6
7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h"
9 #include "base/message_loop.h"
10 #include "chrome/browser/browser.h"
11 #include "chrome/browser/browser_window.h"
12 #include "chrome/browser/tab_contents/tab_contents.h"
13 #include "chrome/browser/tab_contents/tab_contents_view.h"
14 #include "chrome/browser/views/info_bubble.h"
15 #include "chrome/common/notification_observer.h"
16 #include "chrome/common/notification_registrar.h"
17 #include "chrome/common/notification_service.h"
18 #include "chrome/common/notification_type.h"
19 #include "gfx/canvas.h"
20 #include "grit/generated_resources.h"
21 #include "grit/theme_resources.h"
22 #include "views/controls/image_view.h"
23 #include "views/controls/label.h"
24 #include "views/controls/link.h"
25 #include "views/standard_layout.h"
26 #include "views/view.h"
27
28 namespace {
29
30 // The speech bubble's arrow is so many pixels from the left of html element.
31 const int kBubbleTargetOffsetX = 5;
32 const int kBubbleHorizMargin = 40;
33 const int kBubbleVertMargin = 0;
34
35 // This is the content view which is placed inside a SpeechInputBubble.
36 class ContentView
37 : public views::View,
38 public views::LinkController {
39 public:
40 explicit ContentView(SpeechInputBubbleDelegate* delegate);
41
42 void SetRecognizingMode();
43
44 // views::LinkController methods.
45 virtual void LinkActivated(views::Link* source, int event_flags);
46
47 // views::View overrides.
48 virtual gfx::Size GetPreferredSize();
49 virtual void Layout();
50
51 private:
52 SpeechInputBubbleDelegate* delegate_;
53 views::ImageView* icon_;
54 views::Label* heading_;
55 views::Link* cancel_;
56
57 DISALLOW_COPY_AND_ASSIGN(ContentView);
58 };
59
60 ContentView::ContentView(SpeechInputBubbleDelegate* delegate)
61 : delegate_(delegate) {
62 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
63 const gfx::Font& font = rb.GetFont(ResourceBundle::BaseFont);
64
65 heading_ = new views::Label(
66 l10n_util::GetString(IDS_SPEECH_INPUT_BUBBLE_HEADING));
67 heading_->SetFont(font.DeriveFont(3, gfx::Font::NORMAL));
68 heading_->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
69 AddChildView(heading_);
70
71 icon_ = new views::ImageView();
72 icon_->SetImage(*ResourceBundle::GetSharedInstance().GetBitmapNamed(
73 IDR_SPEECH_INPUT_RECORDING));
74 icon_->SetHorizontalAlignment(views::ImageView::CENTER);
75 AddChildView(icon_);
76
77 cancel_ = new views::Link(l10n_util::GetString(IDS_CANCEL));
78 cancel_->SetController(this);
79 cancel_->SetFont(font.DeriveFont(3, gfx::Font::NORMAL));
80 cancel_->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
81 AddChildView(cancel_);
82 }
83
84 void ContentView::SetRecognizingMode() {
85 icon_->SetImage(*ResourceBundle::GetSharedInstance().GetBitmapNamed(
86 IDR_SPEECH_INPUT_PROCESSING));
87 }
88
89 void ContentView::LinkActivated(views::Link* source, int event_flags) {
90 if (source == cancel_) {
91 delegate_->RecognitionCancelled();
92 } else {
93 NOTREACHED() << "Unknown view";
94 }
95 }
96
97 gfx::Size ContentView::GetPreferredSize() {
98 int width = heading_->GetPreferredSize().width();
99 int control_width = cancel_->GetPreferredSize().width();
100 if (control_width > width)
101 width = control_width;
102 control_width = icon_->GetPreferredSize().width();
103 if (control_width > width)
104 width = control_width;
105 width += kBubbleHorizMargin * 2;
106
107 int height = kBubbleVertMargin * 2 +
108 heading_->GetPreferredSize().height() +
109 cancel_->GetPreferredSize().height() +
110 icon_->GetImage().height();
111 return gfx::Size(width, height);
112 }
113
114 void ContentView::Layout() {
115 int x = kBubbleHorizMargin;
116 int y = kBubbleVertMargin;
117 int control_width = width() - kBubbleHorizMargin * 2;
118
119 int height = heading_->GetPreferredSize().height();
120 heading_->SetBounds(x, y, control_width, height);
121 y += height;
122
123 height = icon_->GetImage().height();
124 icon_->SetBounds(x, y, control_width, height);
125 y += height;
126
127 height = cancel_->GetPreferredSize().height();
128 cancel_->SetBounds(x, y, control_width, height);
129 }
130
131 // Implementation of SpeechInputBubble.
132 class SpeechInputBubbleImpl
133 : public SpeechInputBubble,
134 public InfoBubbleDelegate,
135 public NotificationObserver {
136 public:
137 SpeechInputBubbleImpl(TabContents* tab_contents,
138 Delegate* delegate,
sky 2010/08/24 16:08:28 align with ( on previous line.
139 const gfx::Rect& element_rect);
140 ~SpeechInputBubbleImpl();
sky 2010/08/24 16:08:28 virtual
141
142 virtual void SetRecognizingMode();
143
144 // Returns the screen rectangle to use as the info bubble's target.
145 // |element_rect| is the html element's bounds in page coordinates.
146 gfx::Rect GetInfoBubbleTarget(const gfx::Rect& element_rect);
147
148 // NotificationObserver implementation.
149 virtual void Observe(NotificationType type,
150 const NotificationSource& source,
151 const NotificationDetails& details);
152
153 // InfoBubbleDelegate
154 virtual void InfoBubbleClosing(InfoBubble* info_bubble,
155 bool closed_by_escape);
156 virtual bool CloseOnEscape();
157 virtual bool FadeInOnShow();
158
159 private:
160 Delegate* delegate_;
161 InfoBubble* info_bubble_;
162 TabContents* tab_contents_;
163 ContentView* bubble_content_;
164 NotificationRegistrar registrar_;
165 bool did_close_; // Set to true if |Close()| was invoked by caller.
sky 2010/08/24 16:08:28 Update comment.
166
167 DISALLOW_COPY_AND_ASSIGN(SpeechInputBubbleImpl);
168 };
169
170 SpeechInputBubbleImpl::SpeechInputBubbleImpl(TabContents* tab_contents,
171 Delegate* delegate,
172 const gfx::Rect& element_rect)
173 : delegate_(delegate),
174 info_bubble_(NULL),
175 tab_contents_(tab_contents),
176 bubble_content_(NULL),
177 did_close_(false) {
178 bubble_content_ = new ContentView(delegate_);
179
180 views::Widget* parent = views::Widget::GetWidgetFromNativeWindow(
181 tab_contents_->view()->GetTopLevelNativeWindow());
182 info_bubble_ = InfoBubble::Show(parent,
183 GetInfoBubbleTarget(element_rect),
184 BubbleBorder::TOP_LEFT, bubble_content_,
185 this);
186
187 // We don't want fade outs when closing because it makes speech recognition
188 // appear slower than it is. Also setting it to false allows |Close| to
189 // destroy the bubble immediately instead of waiting for the fade animation
190 // to end so the caller can manage this object's life cycle like a normal
191 // stack based or member variable object.
192 info_bubble_->set_fade_away_on_close(false);
193
194 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
195 Source<TabContents>(tab_contents_));
196 }
197
198 SpeechInputBubbleImpl::~SpeechInputBubbleImpl() {
199 if (info_bubble_) {
200 did_close_ = true;
201 info_bubble_->Close();
202 }
203 }
204
205 void SpeechInputBubbleImpl::SetRecognizingMode() {
206 DCHECK(info_bubble_);
207 DCHECK(bubble_content_);
208 bubble_content_->SetRecognizingMode();
209 }
210
211 gfx::Rect SpeechInputBubbleImpl::GetInfoBubbleTarget(
212 const gfx::Rect& element_rect) {
213 gfx::Rect container_rect;
214 tab_contents_->GetContainerBounds(&container_rect);
215 return gfx::Rect(
216 container_rect.x() + element_rect.x() + kBubbleTargetOffsetX,
217 container_rect.y() + element_rect.y() + element_rect.height(), 1, 1);
sky 2010/08/24 16:08:28 Sounds the size be that of element_rect?
Satish 2010/08/24 16:22:04 We want the bubble's arrow to point at x, y positi
218 }
219
220 void SpeechInputBubbleImpl::Observe(NotificationType type,
221 const NotificationSource& source,
222 const NotificationDetails& details) {
223 if (type == NotificationType::TAB_CONTENTS_DESTROYED) {
224 delegate_->RecognitionCancelled();
225 } else {
226 NOTREACHED() << "Unknown notification";
227 }
228 }
229
230 void SpeechInputBubbleImpl::InfoBubbleClosing(InfoBubble* info_bubble,
231 bool closed_by_escape) {
232 registrar_.Remove(this, NotificationType::TAB_CONTENTS_DESTROYED,
233 Source<TabContents>(tab_contents_));
234 info_bubble_ = NULL;
235 bubble_content_ = NULL;
236 if (!did_close_)
237 delegate_->InfoBubbleClosed();
238 }
239
240 bool SpeechInputBubbleImpl::CloseOnEscape() {
241 return false;
242 }
243
244 bool SpeechInputBubbleImpl::FadeInOnShow() {
245 return false;
246 }
247
248 } // namespace
249
250 SpeechInputBubble* SpeechInputBubble::Create(
251 TabContents* tab_contents,
252 SpeechInputBubble::Delegate* delegate,
253 const gfx::Rect& element_rect) {
254 return new SpeechInputBubbleImpl(tab_contents, delegate, element_rect);
255 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698