diff options
author | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-21 21:51:43 +0000 |
---|---|---|
committer | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-21 21:51:43 +0000 |
commit | bd141d8f9578d87ebe7198c94186ba2ce2711312 (patch) | |
tree | 42aa948a353b49df7d276765b1a7f1d9d1b4f82b /chrome/browser/speech | |
parent | b09df81df72de5476a35431d2b1f3793d48ef4f6 (diff) | |
download | chromium_src-bd141d8f9578d87ebe7198c94186ba2ce2711312.zip chromium_src-bd141d8f9578d87ebe7198c94186ba2ce2711312.tar.gz chromium_src-bd141d8f9578d87ebe7198c94186ba2ce2711312.tar.bz2 |
Extend speech input bubble in Mac to display error messages with try-again and cancel buttons.
The SpeechInputBubbleImpl object now lives longer than the actual info bubble window, and
allows the caller to create a bubble on screen or update with an error message when needed.
When recording speech, the layout of controls are (vertical):
- Label ('Speak now')
- Icon (Mic or wait)
- Button Bar (Horizontal, 1 button, 'Cancel')
When showing a message, the layout of controls are (vertical):
- Label (message text)
- Button Bar (Horizontal, 2 buttons, 'Try Again' and 'Cancel')
Also made a small correction to the info bubble's anchor point to get the arrow point at the correct starting point of the given element rect.
XIB changes:
- Added a 'try again' button and hooked it up to the tryAgainButton outlet in the controller
- Moved position of the cancel button for easier editing in interface builder
BUG=53598
TEST=manual, unplug mic and start recognition to check error message, and similarly give no speech to check.
Review URL: http://codereview.chromium.org/3438002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60112 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/speech')
-rw-r--r-- | chrome/browser/speech/speech_input_bubble_browsertest.cc | 55 | ||||
-rw-r--r-- | chrome/browser/speech/speech_input_bubble_mac.mm | 67 | ||||
-rw-r--r-- | chrome/browser/speech/speech_recognizer.cc | 24 |
3 files changed, 110 insertions, 36 deletions
diff --git a/chrome/browser/speech/speech_input_bubble_browsertest.cc b/chrome/browser/speech/speech_input_bubble_browsertest.cc new file mode 100644 index 0000000..fb96593 --- /dev/null +++ b/chrome/browser/speech/speech_input_bubble_browsertest.cc @@ -0,0 +1,55 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_ptr.h" +#include "chrome/browser/speech/speech_input_bubble.h" +#include "chrome/browser/browser.h" +#include "chrome/test/in_process_browser_test.h" +#include "gfx/rect.h" +#include "testing/gtest/include/gtest/gtest.h" + +class SpeechInputBubbleTest : public SpeechInputBubbleDelegate, + public InProcessBrowserTest { + public: + // SpeechInputBubble::Delegate methods. + virtual void InfoBubbleButtonClicked(SpeechInputBubble::Button button) {} + virtual void InfoBubbleFocusChanged() {} + + protected: +}; + +IN_PROC_BROWSER_TEST_F(SpeechInputBubbleTest, CreateAndDestroy) { + gfx::Rect element_rect(100, 100, 100, 100); + scoped_ptr<SpeechInputBubble> bubble(SpeechInputBubble::Create( + browser()->GetSelectedTabContents(), this, element_rect)); + EXPECT_TRUE(bubble.get()); +} + +IN_PROC_BROWSER_TEST_F(SpeechInputBubbleTest, ShowAndDestroy) { + gfx::Rect element_rect(100, 100, 100, 100); + scoped_ptr<SpeechInputBubble> bubble(SpeechInputBubble::Create( + browser()->GetSelectedTabContents(), this, element_rect)); + EXPECT_TRUE(bubble.get()); + bubble->Show(); +} + +IN_PROC_BROWSER_TEST_F(SpeechInputBubbleTest, ShowAndHide) { + gfx::Rect element_rect(100, 100, 100, 100); + scoped_ptr<SpeechInputBubble> bubble(SpeechInputBubble::Create( + browser()->GetSelectedTabContents(), this, element_rect)); + EXPECT_TRUE(bubble.get()); + bubble->Show(); + bubble->Hide(); +} + +IN_PROC_BROWSER_TEST_F(SpeechInputBubbleTest, ShowAndHideTwice) { + gfx::Rect element_rect(100, 100, 100, 100); + scoped_ptr<SpeechInputBubble> bubble(SpeechInputBubble::Create( + browser()->GetSelectedTabContents(), this, element_rect)); + EXPECT_TRUE(bubble.get()); + bubble->Show(); + bubble->Hide(); + bubble->Show(); + bubble->Hide(); +} diff --git a/chrome/browser/speech/speech_input_bubble_mac.mm b/chrome/browser/speech/speech_input_bubble_mac.mm index f22db5f..a48eac6 100644 --- a/chrome/browser/speech/speech_input_bubble_mac.mm +++ b/chrome/browser/speech/speech_input_bubble_mac.mm @@ -10,6 +10,7 @@ #import "chrome/browser/cocoa/speech_input_window_controller.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" +#include "skia/ext/skia_utils_mac.h" namespace { @@ -29,51 +30,69 @@ class SpeechInputBubbleImpl : public SpeechInputBubbleBase { private: scoped_nsobject<SpeechInputWindowController> window_; + TabContents* tab_contents_; + Delegate* delegate_; + gfx::Rect element_rect_; }; SpeechInputBubbleImpl::SpeechInputBubbleImpl(TabContents* tab_contents, Delegate* delegate, - const gfx::Rect& element_rect) { + const gfx::Rect& element_rect) + : tab_contents_(tab_contents), + delegate_(delegate), + element_rect_(element_rect) { +} + +SpeechInputBubbleImpl::~SpeechInputBubbleImpl() { + if (window_.get()) + [window_.get() close]; +} + +void SpeechInputBubbleImpl::SetImage(const SkBitmap& image) { + if (window_.get()) + [window_.get() setImage:gfx::SkBitmapToNSImage(image)]; +} + +void SpeechInputBubbleImpl::Show() { + if (window_.get()) { + [window_.get() show]; + return; + } + // Find the screen coordinates for the given tab and position the bubble's // arrow anchor point inside that to point at the bottom-left of the html // input element rect. - gfx::NativeView view = tab_contents->view()->GetNativeView(); + gfx::NativeView view = tab_contents_->view()->GetNativeView(); NSRect tab_bounds = [view bounds]; NSPoint anchor = NSMakePoint( - tab_bounds.origin.x + element_rect.x() + kBubbleTargetOffsetX, - tab_bounds.origin.y + tab_bounds.size.height - element_rect.y() - - element_rect.height()); + tab_bounds.origin.x + element_rect_.x() + kBubbleTargetOffsetX, + tab_bounds.origin.y + tab_bounds.size.height - element_rect_.y() - + element_rect_.height()); anchor = [view convertPoint:anchor toView:nil]; anchor = [[view window] convertBaseToScreen:anchor]; window_.reset([[SpeechInputWindowController alloc] - initWithParentWindow:tab_contents->view()->GetTopLevelNativeWindow() - delegate:delegate + initWithParentWindow:tab_contents_->view()->GetTopLevelNativeWindow() + delegate:delegate_ anchoredAt:anchor]); -} -SpeechInputBubbleImpl::~SpeechInputBubbleImpl() { - [window_.get() close]; -} - -void SpeechInputBubbleImpl::SetImage(const SkBitmap& image) { - // TODO(satish): Implement. - NOTREACHED(); -} - -void SpeechInputBubbleImpl::Show() { - // TODO(satish): Implement. - NOTREACHED(); + UpdateLayout(); } void SpeechInputBubbleImpl::Hide() { - // TODO(satish): Implement. - NOTREACHED(); + if (!window_.get()) + return; + + [window_.get() close]; + window_.reset(); } void SpeechInputBubbleImpl::UpdateLayout() { - // TODO(satish): Implement. - NOTREACHED(); + if (!window_.get()) + return; + + [window_.get() updateLayout:display_mode() + messageText:message_text()]; } } // namespace diff --git a/chrome/browser/speech/speech_recognizer.cc b/chrome/browser/speech/speech_recognizer.cc index 6eed2f5..ce1bfaa 100644 --- a/chrome/browser/speech/speech_recognizer.cc +++ b/chrome/browser/speech/speech_recognizer.cc @@ -31,11 +31,11 @@ COMPILE_ASSERT(kMaxSpeexFrameLength <= 0xFF, invalidLength); // The following constants are related to the volume level indicator shown in // the UI for recorded audio. // Multiplier used when new volume is greater than previous level. -const float kUpSmoothingFactor = 0.9f;
-// Multiplier used when new volume is lesser than previous level.
-const float kDownSmoothingFactor = 0.4f;
-const float kAudioMeterMinDb = 10.0f; // Lower bar for volume meter.
-const float kAudioMeterDbRange = 25.0f;
+const float kUpSmoothingFactor = 0.9f; +// Multiplier used when new volume is lesser than previous level. +const float kDownSmoothingFactor = 0.4f; +const float kAudioMeterMinDb = 10.0f; // Lower bar for volume meter. +const float kAudioMeterDbRange = 25.0f; } // namespace namespace speech_input { @@ -293,13 +293,13 @@ void SpeechRecognizer::HandleOnData(string* data) { // Calculate the input volume to display in the UI, smoothing towards the // new level. - float level = (rms - kAudioMeterMinDb) / kAudioMeterDbRange;
- level = std::min(std::max(0.0f, level), 1.0f);
- if (level > audio_level_) {
- audio_level_ += (level - audio_level_) * kUpSmoothingFactor;
- } else {
- audio_level_ += (level - audio_level_) * kDownSmoothingFactor;
- }
+ float level = (rms - kAudioMeterMinDb) / kAudioMeterDbRange; + level = std::min(std::max(0.0f, level), 1.0f); + if (level > audio_level_) { + audio_level_ += (level - audio_level_) * kUpSmoothingFactor; + } else { + audio_level_ += (level - audio_level_) * kDownSmoothingFactor; + } delegate_->SetInputVolume(caller_id_, audio_level_); if (endpointer_.speech_input_complete()) { |