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 | |
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')
-rw-r--r-- | chrome/app/nibs/SpeechInputBubble.xib | 92 | ||||
-rw-r--r-- | chrome/browser/cocoa/speech_input_window_controller.h | 22 | ||||
-rw-r--r-- | chrome/browser/cocoa/speech_input_window_controller.mm | 124 | ||||
-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 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 |
7 files changed, 304 insertions, 81 deletions
diff --git a/chrome/app/nibs/SpeechInputBubble.xib b/chrome/app/nibs/SpeechInputBubble.xib index b939d96..4f2e84b5 100644 --- a/chrome/app/nibs/SpeechInputBubble.xib +++ b/chrome/app/nibs/SpeechInputBubble.xib @@ -57,21 +57,41 @@ <int key="NSvFlags">301</int> <object class="NSMutableArray" key="NSSubviews"> <bool key="EncodedWithXMLCoder">YES</bool> - <object class="NSButton" id="789820196"> + <object class="NSButton" id="1038338233"> <reference key="NSNextResponder" ref="926910107"/> <int key="NSvFlags">268</int> - <string key="NSFrame">{{47, 12}, {96, 32}}</string> + <string key="NSFrame">{{14, 12}, {82, 32}}</string> <reference key="NSSuperview" ref="926910107"/> <bool key="NSEnabled">YES</bool> - <object class="NSButtonCell" key="NSCell" id="541512844"> + <object class="NSButtonCell" key="NSCell" id="84459405"> <int key="NSCellFlags">67239424</int> <int key="NSCellFlags2">134217728</int> - <string key="NSContents">^IDS_CANCEL</string> + <string key="NSContents">^IDS_SPEECH_INPUT_TRY_AGAIN</string> <object class="NSFont" key="NSSupport" id="487155245"> <string key="NSName">LucidaGrande</string> <double key="NSSize">13</double> <int key="NSfFlags">1044</int> </object> + <reference key="NSControlView" ref="1038338233"/> + <int key="NSButtonFlags">-2038284033</int> + <int key="NSButtonFlags2">129</int> + <string key="NSAlternateContents"/> + <string key="NSKeyEquivalent"/> + <int key="NSPeriodicDelay">200</int> + <int key="NSPeriodicInterval">25</int> + </object> + </object> + <object class="NSButton" id="789820196"> + <reference key="NSNextResponder" ref="926910107"/> + <int key="NSvFlags">268</int> + <string key="NSFrame">{{88, 12}, {88, 32}}</string> + <reference key="NSSuperview" ref="926910107"/> + <bool key="NSEnabled">YES</bool> + <object class="NSButtonCell" key="NSCell" id="541512844"> + <int key="NSCellFlags">67239424</int> + <int key="NSCellFlags2">134217728</int> + <string key="NSContents">^IDS_CANCEL</string> + <reference key="NSSupport" ref="487155245"/> <reference key="NSControlView" ref="789820196"/> <int key="NSButtonFlags">-2038284033</int> <int key="NSButtonFlags2">129</int> @@ -236,6 +256,22 @@ </object> <int key="connectionID">837</int> </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">tryAgainButton_</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="1038338233"/> + </object> + <int key="connectionID">840</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">tryAgain:</string> + <reference key="source" ref="1021"/> + <reference key="destination" ref="1038338233"/> + </object> + <int key="connectionID">841</int> + </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> @@ -300,6 +336,7 @@ <reference ref="530565492"/> <reference ref="793691203"/> <reference ref="789820196"/> + <reference ref="1038338233"/> </object> <reference key="parent" ref="414427165"/> </object> @@ -345,6 +382,20 @@ <reference key="object" ref="541512844"/> <reference key="parent" ref="789820196"/> </object> + <object class="IBObjectRecord"> + <int key="objectID">838</int> + <reference key="object" ref="1038338233"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="84459405"/> + </object> + <reference key="parent" ref="926910107"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">839</int> + <reference key="object" ref="84459405"/> + <reference key="parent" ref="1038338233"/> + </object> </object> </object> <object class="NSMutableDictionary" key="flattenedProperties"> @@ -366,13 +417,15 @@ <string>815.IBPluginDependency</string> <string>816.IBPluginDependency</string> <string>825.IBPluginDependency</string> + <string>838.IBPluginDependency</string> + <string>839.IBPluginDependency</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{452, 1286}, {190, 190}}</string> + <string>{{593, 566}, {190, 190}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{452, 1286}, {190, 190}}</string> + <string>{{593, 566}, {190, 190}}</string> <boolean value="NO"/> <string>{{11, 666}, {480, 270}}</string> <string>{3.40282e+38, 3.40282e+38}</string> @@ -384,6 +437,8 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> </object> </object> <object class="NSMutableDictionary" key="unlocalizedProperties"> @@ -402,7 +457,7 @@ </object> </object> <nil key="sourceID"/> - <int key="maxID">837</int> + <int key="maxID">841</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> @@ -557,8 +612,17 @@ <string key="className">SpeechInputWindowController</string> <string key="superclassName">BaseBubbleController</string> <object class="NSMutableDictionary" key="actions"> - <string key="NS.key.0">cancel:</string> - <string key="NS.object.0">id</string> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>cancel:</string> + <string>tryAgain:</string> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>id</string> + <string>id</string> + </object> </object> <object class="NSMutableDictionary" key="outlets"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -567,12 +631,14 @@ <string>cancelButton_</string> <string>iconImage_</string> <string>instructionLabel_</string> + <string>tryAgainButton_</string> </object> <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>NSButton</string> <string>NSImageView</string> <string>NSTextField</string> + <string>NSButton</string> </object> </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> @@ -580,6 +646,14 @@ <string key="minorKey">browser/cocoa/speech_input_window_controller.h</string> </object> </object> + <object class="IBPartialClassDescription"> + <string key="className">SpeechInputWindowController</string> + <string key="superclassName">BaseBubbleController</string> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBUserSource</string> + <string key="minorKey"/> + </object> + </object> </object> <object class="NSMutableArray" key="referencedPartialClassDescriptionsV3.2+"> <bool key="EncodedWithXMLCoder">YES</bool> diff --git a/chrome/browser/cocoa/speech_input_window_controller.h b/chrome/browser/cocoa/speech_input_window_controller.h index 51f6b8d..11000c2 100644 --- a/chrome/browser/cocoa/speech_input_window_controller.h +++ b/chrome/browser/cocoa/speech_input_window_controller.h @@ -21,6 +21,7 @@ IBOutlet NSImageView* iconImage_; IBOutlet NSTextField* instructionLabel_; IBOutlet NSButton* cancelButton_; + IBOutlet NSButton* tryAgainButton_; } // Initialize the window. |anchoredAt| is in screen coordinates. @@ -31,8 +32,25 @@ // Handler for the cancel button. - (IBAction)cancel:(id)sender; -// Inform the user that audio recording has ended and recognition is underway. -- (void)didStartRecognition; +// Handler for the try again button. +- (IBAction)tryAgain:(id)sender; + +// Updates the UI with data related to the given display mode. +- (void)updateLayout:(SpeechInputBubbleBase::DisplayMode)mode + messageText:(const string16&)messageText; + +// Makes the speech input bubble visible on screen. +- (void)show; + +// Hides the speech input bubble away from screen. This does NOT release the +// controller and the window. +- (void)hide; + +// Sets the image to be displayed in the bubble's status ImageView. A future +// call to updateLayout may change the image. +// TODO(satish): Clean that up and move it into the platform independent +// SpeechInputBubbleBase class. +- (void)setImage:(NSImage*)image; @end diff --git a/chrome/browser/cocoa/speech_input_window_controller.mm b/chrome/browser/cocoa/speech_input_window_controller.mm index c3dae85..6e8e862 100644 --- a/chrome/browser/cocoa/speech_input_window_controller.mm +++ b/chrome/browser/cocoa/speech_input_window_controller.mm @@ -4,10 +4,12 @@ #import "speech_input_window_controller.h" -#include "app/l10n_util.h" +#include "app/l10n_util_mac.h" #include "app/resource_bundle.h" +#include "base/logging.h" #include "base/mac_util.h" #include "base/sys_string_conversions.h" + #include "chrome/browser/cocoa/info_bubble_view.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" @@ -15,7 +17,7 @@ #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" const int kBubbleControlVerticalSpacing = 10; // Space between controls. -const int kBubbleHorizontalMargin = 15; // Space on either sides of controls. +const int kBubbleHorizontalMargin = 5; // Space on either sides of controls. @interface SpeechInputWindowController (Private) - (NSSize)calculateContentSize; @@ -28,7 +30,9 @@ const int kBubbleHorizontalMargin = 15; // Space on either sides of controls. delegate:(SpeechInputBubbleDelegate*)delegate anchoredAt:(NSPoint)anchoredAt { anchoredAt.x -= info_bubble::kBubbleArrowXOffset + + info_bubble::kBubbleCornerRadius + info_bubble::kBubbleArrowWidth / 2.0; + anchoredAt.y += info_bubble::kBubbleArrowHeight / 2.0; if ((self = [super initWithWindowNibPath:@"SpeechInputBubble" parentWindow:parentWindow anchoredAt:anchoredAt])) { @@ -43,10 +47,6 @@ const int kBubbleHorizontalMargin = 15; // Space on either sides of controls. - (void)awakeFromNib { NSWindow* window = [self window]; [[self bubble] setArrowLocation:info_bubble::kTopLeft]; - NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed( - IDR_SPEECH_INPUT_MIC_EMPTY); - [iconImage_ setImage:icon]; - [iconImage_ setNeedsDisplay:YES]; NSSize newSize = [self calculateContentSize]; [[self bubble] setFrameSize:newSize]; @@ -66,25 +66,35 @@ const int kBubbleHorizontalMargin = 15; // Space on either sides of controls. delegate_->InfoBubbleButtonClicked(SpeechInputBubble::BUTTON_CANCEL); } +- (IBAction)tryAgain:(id)sender { + delegate_->InfoBubbleButtonClicked(SpeechInputBubble::BUTTON_TRY_AGAIN); +} + // Calculate the window dimensions to reflect the sum height and max width of // all controls, with appropriate spacing between and around them. The returned // size is in view coordinates. - (NSSize)calculateContentSize { [GTMUILocalizerAndLayoutTweaker sizeToFitView:cancelButton_]; - NSSize size = [cancelButton_ bounds].size; - int newHeight = size.height + kBubbleControlVerticalSpacing; - int newWidth = size.width; - - NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed( - IDR_SPEECH_INPUT_MIC_EMPTY); - size = [icon size]; - newHeight += size.height + kBubbleControlVerticalSpacing; - if (newWidth < size.width) - newWidth = size.width; + [GTMUILocalizerAndLayoutTweaker sizeToFitView:tryAgainButton_]; + NSSize cancelSize = [cancelButton_ bounds].size; + NSSize tryAgainSize = [tryAgainButton_ bounds].size; + int newHeight = cancelSize.height + kBubbleControlVerticalSpacing; + int newWidth = cancelSize.width + tryAgainSize.width; + + if (![iconImage_ isHidden]) { + NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed( + IDR_SPEECH_INPUT_MIC_EMPTY); + NSSize size = [icon size]; + newHeight += size.height + kBubbleControlVerticalSpacing; + if (newWidth < size.width) + newWidth = size.width; + } else { + newHeight += kBubbleControlVerticalSpacing; + } [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: instructionLabel_]; - size = [instructionLabel_ bounds].size; + NSSize size = [instructionLabel_ bounds].size; newHeight += size.height; if (newWidth < size.width) newWidth = size.width; @@ -97,33 +107,79 @@ const int kBubbleHorizontalMargin = 15; // Space on either sides of controls. - (void)layout:(NSSize)size { int y = kBubbleControlVerticalSpacing; - NSRect rect = [cancelButton_ bounds]; - rect.origin.x = (size.width - rect.size.width) / 2; - rect.origin.y = y; - [cancelButton_ setFrame:rect]; - y += rect.size.height + kBubbleControlVerticalSpacing; - - rect = [iconImage_ bounds]; - rect.origin.x = (size.width - rect.size.width) / 2; - rect.origin.y = y; - [iconImage_ setFrame:rect]; - y += rect.size.height + kBubbleControlVerticalSpacing; + NSRect cancelRect = [cancelButton_ bounds]; + + if ([tryAgainButton_ isHidden]) { + cancelRect.origin.x = (size.width - NSWidth(cancelRect)) / 2; + } else { + NSRect tryAgainRect = [tryAgainButton_ bounds]; + cancelRect.origin.x = (size.width - NSWidth(cancelRect) - + NSWidth(tryAgainRect)) / 2; + tryAgainRect.origin.x = cancelRect.origin.x + NSWidth(cancelRect); + tryAgainRect.origin.y = y; + [tryAgainButton_ setFrame:tryAgainRect]; + } + cancelRect.origin.y = y; + [cancelButton_ setFrame:cancelRect]; + + y += NSHeight(cancelRect) + kBubbleControlVerticalSpacing; + + NSRect rect; + if (![iconImage_ isHidden]) { + rect = [iconImage_ bounds]; + rect.origin.x = (size.width - NSWidth(rect)) / 2; + rect.origin.y = y; + [iconImage_ setFrame:rect]; + y += rect.size.height + kBubbleControlVerticalSpacing; + } rect = [instructionLabel_ bounds]; - rect.origin.x = (size.width - rect.size.width) / 2; + rect.origin.x = (size.width - NSWidth(rect)) / 2; rect.origin.y = y; [instructionLabel_ setFrame:rect]; } -- (void)didStartRecognition { - NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed( - IDR_SPEECH_INPUT_PROCESSING); - [iconImage_ setImage:icon]; - [iconImage_ setNeedsDisplay:YES]; +- (void)updateLayout:(SpeechInputBubbleBase::DisplayMode)mode + messageText:(const string16&)messageText { + // Get the right set of controls to be visible. + if (mode == SpeechInputBubbleBase::DISPLAY_MODE_MESSAGE) { + [instructionLabel_ setStringValue:base::SysUTF16ToNSString(messageText)]; + [iconImage_ setHidden:YES]; + [tryAgainButton_ setHidden:NO]; + } else { + [instructionLabel_ setStringValue:l10n_util::GetNSString( + IDS_SPEECH_INPUT_BUBBLE_HEADING)]; + NSImage* icon = ResourceBundle::GetSharedInstance().GetNSImageNamed( + (mode == SpeechInputBubbleBase::DISPLAY_MODE_RECORDING ? + IDR_SPEECH_INPUT_MIC_EMPTY : IDR_SPEECH_INPUT_PROCESSING)); + [iconImage_ setImage:icon]; + [iconImage_ setHidden:NO]; + [iconImage_ setNeedsDisplay:YES]; + [tryAgainButton_ setHidden:YES]; + } + + NSSize newSize = [self calculateContentSize]; + NSRect rect = [[self bubble] frame]; + rect.origin.y -= newSize.height - rect.size.height; + rect.size = newSize; + [[self bubble] setFrame:rect]; + [self layout:newSize]; } - (void)windowWillClose:(NSNotification*)notification { delegate_->InfoBubbleFocusChanged(); } +- (void)show { + [self showWindow:nil]; +} + +- (void)hide { + [[self window] orderOut:nil]; +} + +- (void)setImage:(NSImage*)image { + [iconImage_ setImage:image]; +} + @end // implementation SpeechInputWindowController 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()) { diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index acdbca3..9bbe65a 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1785,6 +1785,7 @@ 'browser/sessions/tab_restore_service_browsertest.cc', 'browser/speech/enable_speech_input_switch_browsertest.cc', 'browser/speech/speech_input_browsertest.cc', + 'browser/speech/speech_input_bubble_browsertest.cc', 'browser/ssl/ssl_browser_tests.cc', 'browser/task_manager_browsertest.cc', 'browser/views/browser_actions_container_browsertest.cc', |