OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/tab_contents/tab_contents.h" | 5 #include "chrome/browser/tab_contents/tab_contents.h" |
6 #include "chrome/browser/speech/speech_input_bubble.h" | 6 #include "chrome/browser/speech/speech_input_bubble.h" |
7 #include "grit/generated_resources.h" | 7 #include "grit/generated_resources.h" |
8 #include "grit/theme_resources.h" | 8 #include "grit/theme_resources.h" |
9 #include "ui/base/resource/resource_bundle.h" | 9 #include "ui/base/resource/resource_bundle.h" |
10 #include "ui/gfx/canvas_skia.h" | 10 #include "ui/gfx/canvas_skia.h" |
11 #include "ui/gfx/rect.h" | 11 #include "ui/gfx/rect.h" |
12 | 12 |
13 SpeechInputBubble::FactoryMethod SpeechInputBubble::factory_ = NULL; | 13 SpeechInputBubble::FactoryMethod SpeechInputBubble::factory_ = NULL; |
14 const int SpeechInputBubble::kBubbleTargetOffsetX = 5; | 14 const int SpeechInputBubble::kBubbleTargetOffsetX = 10; |
15 | 15 |
16 SkBitmap* SpeechInputBubbleBase::mic_empty_ = NULL; | 16 SkBitmap* SpeechInputBubbleBase::mic_empty_ = NULL; |
17 SkBitmap* SpeechInputBubbleBase::mic_noise_ = NULL; | |
17 SkBitmap* SpeechInputBubbleBase::mic_full_ = NULL; | 18 SkBitmap* SpeechInputBubbleBase::mic_full_ = NULL; |
18 SkBitmap* SpeechInputBubbleBase::mic_mask_ = NULL; | 19 SkBitmap* SpeechInputBubbleBase::mic_mask_ = NULL; |
19 SkBitmap* SpeechInputBubbleBase::spinner_ = NULL; | 20 SkBitmap* SpeechInputBubbleBase::spinner_ = NULL; |
20 const int SpeechInputBubbleBase::kRecognizingAnimationStepMs = 100; | 21 const int SpeechInputBubbleBase::kRecognizingAnimationStepMs = 100; |
21 | 22 |
22 SpeechInputBubble* SpeechInputBubble::Create(TabContents* tab_contents, | 23 SpeechInputBubble* SpeechInputBubble::Create(TabContents* tab_contents, |
23 Delegate* delegate, | 24 Delegate* delegate, |
24 const gfx::Rect& element_rect) { | 25 const gfx::Rect& element_rect) { |
25 if (factory_) | 26 if (factory_) |
26 return (*factory_)(tab_contents, delegate, element_rect); | 27 return (*factory_)(tab_contents, delegate, element_rect); |
27 | 28 |
28 // Has the tab already closed before bubble create request was processed? | 29 // Has the tab already closed before bubble create request was processed? |
29 if (!tab_contents) | 30 if (!tab_contents) |
30 return NULL; | 31 return NULL; |
31 | 32 |
32 return CreateNativeBubble(tab_contents, delegate, element_rect); | 33 return CreateNativeBubble(tab_contents, delegate, element_rect); |
33 } | 34 } |
34 | 35 |
35 SpeechInputBubbleBase::SpeechInputBubbleBase(TabContents* tab_contents) | 36 SpeechInputBubbleBase::SpeechInputBubbleBase(TabContents* tab_contents) |
36 : ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), | 37 : ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), |
37 display_mode_(DISPLAY_MODE_RECORDING), | 38 display_mode_(DISPLAY_MODE_RECORDING), |
38 tab_contents_(tab_contents) { | 39 tab_contents_(tab_contents) { |
39 if (!mic_empty_) { // Static variables. | 40 if (!mic_empty_) { // Static variables. |
40 mic_empty_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( | 41 mic_empty_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
41 IDR_SPEECH_INPUT_MIC_EMPTY); | 42 IDR_SPEECH_INPUT_MIC_EMPTY); |
43 mic_noise_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
44 IDR_SPEECH_INPUT_MIC_NOISE); | |
42 mic_full_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( | 45 mic_full_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
43 IDR_SPEECH_INPUT_MIC_FULL); | 46 IDR_SPEECH_INPUT_MIC_FULL); |
44 mic_mask_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( | 47 mic_mask_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
45 IDR_SPEECH_INPUT_MIC_MASK); | 48 IDR_SPEECH_INPUT_MIC_MASK); |
46 spinner_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( | 49 spinner_ = ResourceBundle::GetSharedInstance().GetBitmapNamed( |
47 IDR_SPEECH_INPUT_SPINNER); | 50 IDR_SPEECH_INPUT_SPINNER); |
48 } | 51 } |
49 | 52 |
50 // Instance variables. | 53 // Instance variables. |
51 mic_image_.reset(new SkBitmap()); | 54 mic_image_.reset(new SkBitmap()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 } | 89 } |
87 | 90 |
88 void SpeechInputBubbleBase::SetRecordingMode() { | 91 void SpeechInputBubbleBase::SetRecordingMode() { |
89 task_factory_.RevokeAll(); | 92 task_factory_.RevokeAll(); |
90 display_mode_ = DISPLAY_MODE_RECORDING; | 93 display_mode_ = DISPLAY_MODE_RECORDING; |
91 UpdateLayout(); | 94 UpdateLayout(); |
92 } | 95 } |
93 | 96 |
94 void SpeechInputBubbleBase::SetRecognizingMode() { | 97 void SpeechInputBubbleBase::SetRecognizingMode() { |
95 display_mode_ = DISPLAY_MODE_RECOGNIZING; | 98 display_mode_ = DISPLAY_MODE_RECOGNIZING; |
99 animation_step_ = 0; | |
100 DoRecognizingAnimationStep(); | |
96 UpdateLayout(); | 101 UpdateLayout(); |
97 | |
98 animation_step_ = 0; | |
99 MessageLoop::current()->PostDelayedTask( | |
100 FROM_HERE, | |
101 task_factory_.NewRunnableMethod( | |
102 &SpeechInputBubbleBase::DoRecognizingAnimationStep), | |
103 kRecognizingAnimationStepMs); | |
104 } | 102 } |
105 | 103 |
106 void SpeechInputBubbleBase::DoRecognizingAnimationStep() { | 104 void SpeechInputBubbleBase::DoRecognizingAnimationStep() { |
107 SetImage(animation_frames_[animation_step_]); | 105 SetImage(animation_frames_[animation_step_]); |
108 if (++animation_step_ >= static_cast<int>(animation_frames_.size())) | 106 if (++animation_step_ >= static_cast<int>(animation_frames_.size())) |
109 animation_step_ = 0; | 107 animation_step_ = 0; |
110 MessageLoop::current()->PostDelayedTask( | 108 MessageLoop::current()->PostDelayedTask( |
111 FROM_HERE, | 109 FROM_HERE, |
112 task_factory_.NewRunnableMethod( | 110 task_factory_.NewRunnableMethod( |
113 &SpeechInputBubbleBase::DoRecognizingAnimationStep), | 111 &SpeechInputBubbleBase::DoRecognizingAnimationStep), |
114 kRecognizingAnimationStepMs); | 112 kRecognizingAnimationStepMs); |
115 } | 113 } |
116 | 114 |
117 void SpeechInputBubbleBase::SetMessage(const string16& text) { | 115 void SpeechInputBubbleBase::SetMessage(const string16& text) { |
118 task_factory_.RevokeAll(); | 116 task_factory_.RevokeAll(); |
119 message_text_ = text; | 117 message_text_ = text; |
120 display_mode_ = DISPLAY_MODE_MESSAGE; | 118 display_mode_ = DISPLAY_MODE_MESSAGE; |
121 UpdateLayout(); | 119 UpdateLayout(); |
122 } | 120 } |
123 | 121 |
124 void SpeechInputBubbleBase::SetInputVolume(float volume) { | 122 void SpeechInputBubbleBase::DrawVolumeOverlay(SkCanvas& canvas, |
125 mic_image_->eraseARGB(0, 0, 0, 0); | 123 SkBitmap* bitmap, |
124 float volume) { | |
126 buffer_image_->eraseARGB(0, 0, 0, 0); | 125 buffer_image_->eraseARGB(0, 0, 0, 0); |
127 | 126 |
128 int width = mic_image_->width(); | 127 int width = mic_image_->width(); |
129 int height = mic_image_->height(); | 128 int height = mic_image_->height(); |
130 SkCanvas canvas(*mic_image_); | |
131 SkCanvas buffer_canvas(*buffer_image_); | 129 SkCanvas buffer_canvas(*buffer_image_); |
132 | 130 |
133 // The 'full volume' mic image is drawn clipped to the current volume level, | |
134 // and a gradient mask is applied over it with the 'multiply' compositing | |
135 // operator to show soft edges at the top. | |
136 buffer_canvas.save(); | 131 buffer_canvas.save(); |
137 SkScalar clip_top = ((1.0f - volume) * height * 3) / 2.0f - height / 2.0f; | 132 SkScalar clip_right = (((1.0f - volume) * (width * 13)) - width) / 12.0f; |
bulach
2011/03/01 17:39:04
it'd be great to have these magical 13 and 12.0 as
| |
138 buffer_canvas.clipRect(SkRect::MakeLTRB(0, clip_top, | 133 buffer_canvas.clipRect(SkRect::MakeLTRB(0, 0, |
139 SkIntToScalar(width), SkIntToScalar(height))); | 134 SkIntToScalar(width) - clip_right, SkIntToScalar(height))); |
140 buffer_canvas.drawBitmap(*mic_full_, 0, 0); | 135 buffer_canvas.drawBitmap(*bitmap, 0, 0); |
bulach
2011/03/01 17:39:04
I guess bitmap can be const&
| |
141 buffer_canvas.restore(); | 136 buffer_canvas.restore(); |
142 SkPaint multiply_paint; | 137 SkPaint multiply_paint; |
143 multiply_paint.setXfermode(SkXfermode::Create(SkXfermode::kMultiply_Mode)); | 138 multiply_paint.setXfermode(SkXfermode::Create(SkXfermode::kMultiply_Mode)); |
144 buffer_canvas.drawBitmap(*mic_mask_, 0, clip_top, &multiply_paint); | 139 buffer_canvas.drawBitmap(*mic_mask_, -clip_right, 0, &multiply_paint); |
145 | 140 |
146 // Draw the empty volume image first and the current volume image on top. | 141 canvas.drawBitmap(*buffer_image_.get(), 0, 0); |
bulach
2011/03/01 17:39:04
and canvas a *
| |
142 } | |
143 | |
144 void SpeechInputBubbleBase::SetInputVolume(float volume, float noise_volume) { | |
145 mic_image_->eraseARGB(0, 0, 0, 0); | |
146 SkCanvas canvas(*mic_image_); | |
147 | |
148 // Draw the empty volume image first and the current volume image on top, | |
149 // and then the noise volume image on top of both. | |
147 canvas.drawBitmap(*mic_empty_, 0, 0); | 150 canvas.drawBitmap(*mic_empty_, 0, 0); |
148 canvas.drawBitmap(*buffer_image_.get(), 0, 0); | 151 DrawVolumeOverlay(canvas, mic_full_, volume); |
152 DrawVolumeOverlay(canvas, mic_noise_, noise_volume); | |
149 | 153 |
150 SetImage(*mic_image_.get()); | 154 SetImage(*mic_image_.get()); |
151 } | 155 } |
152 | 156 |
153 TabContents* SpeechInputBubbleBase::tab_contents() { | 157 TabContents* SpeechInputBubbleBase::tab_contents() { |
154 return tab_contents_; | 158 return tab_contents_; |
155 } | 159 } |
OLD | NEW |